Language/JAVA

[JAVA] 리플렉션

IT수정 2024. 10. 16. 12:04

리플렉션

자바는 클래스와 인터페이스의 메타 정보를 Class 객체로 관리한다. 여기서 메타 정보란 패키지 정보, 타입 정보, 멤버(생성자, 필드, 메서드) 정보 등을 말한다. 이러한 메타 정보를 프로그램에서 읽고 수정하는 행위를 리플렉션이라고 한다. 프로그램에서 Class 객체를 얻으려면 다음 3가지 방법 중 하나를 이용하면 된다.

① Class clazz = 클래스이름.class;
② Class clazz = Class.forName("패키지...클래스이름");
③ Class clazz = 객체참조변수.getClass(); // 객체로부터 얻는 방법

 

셋 중 어떤 방법을 사용하더라고 동일한 Class 객체를 얻을 수 있다. 예를 들어 String 클래스의  Class 객체는 다음과 같이 얻을 수 있다.

Class clazz = String.class;

Class clazz = Class.forName("java.lang.String");

String str = "김자바";
Class clazz = str.getClass();

 

패키지와 타입 정보 얻기

패키지와 타입(클래스, 인터페이스) 이름 정보는 다음 메서드를 통해 얻을 수 있다.

메서드 용도
Package getPackage() 패키지 정보 읽기
String getSimpleName() 패키지를 제외한 타입 이름
String getName() 패키지를 포함한 전체 타입 이름

 

예제 코드

Car.java

package ch12;

public class Car {

}

 

GetClassExample.java

package ch12;

public class GetClassExample {

	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		Class clazz = Car.class;
		
		//Class clazz = Class.forName("ch12.Car");
		
		//Car car = new Car();
		//Class clazz = car.getClass();
		
		System.out.println("패키지: " + clazz.getPackage().getName());
		System.out.println("클래스 간단 이름: " + clazz.getSimpleName());
		System.out.println("클래스 전체 이름: " + clazz.getName());
	}

}

 

출력 결과

패키지: ch12
클래스 간단 이름: Car
클래스 전체 이름: ch12.Car

 

멤버 정보 얻기

타입(클래스, 인터페이스)이 가지고 있는 멤버 정보는 다음 메서드를 통해 얻을 수 있다.

메서드 용도
Constructor[] getDeclaredConstructors() 생성자 정보 읽기
Field[] getDeclaredFields() 필드 정보 읽기
Method[] getDeclaredMethods() 메서드 정보 읽기

 

예제 코드

Car.java

package ch12;

public class Car {
	private String model;
	private String owner;
	
	public Car() {
	}
	
	public Car(String model) {
		this.model = model;
	}
	
	public String getModel() { return model; }
	public void setModel(String model) { this.model = model; }
	public String getOwner() {return owner; }
	public void setOwner(String owner) { this.owner = owner; }
}

 

RefelctionExample.java

package ch12;

import java.lang.reflect.*;

public class ReflectionExample {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Class clazz = Car.class;
		
		System.out.println("[생성자 정보]");
		Constructor[] constructors = clazz.getDeclaredConstructors();
		for(Constructor constructor : constructors) {
			System.out.print(constructor.getName() + "(");
			Class[] parameters = constructor.getParameterTypes();
			printParameters(parameters);
			System.out.println(")");
		}
		System.out.println();
		
		System.out.println("[필드 정보]");
		Field[] fields = clazz.getDeclaredFields();
		for(Field field : fields) {
			System.out.println(field.getType().getName() + " " + field.getName());
		}
		System.out.println();
		
		System.out.println("[메서드 정보]");
		Method[] methods = clazz.getDeclaredMethods();
		for(Method method : methods) {
			System.out.print(method.getName() + "(");
			Class[] parameters = method.getParameterTypes();
			printParameters(parameters);
			System.out.println(")");
		}
	}
	
	private static void printParameters(Class[] parameters) {
		for(int i=0; i<parameters.length; i++) {
			System.out.print(parameters[i].getName());
			if(i<(parameters.length - 1)) {
				System.out.print(",");
			}
		}
	}

}

 

출력 결과

[생성자 정보]
ch12.Car()
ch12.Car(java.lang.String)

[필드 정보]
java.lang.String model
java.lang.String owner

[메서드 정보]
getOwner()
getModel()
setModel(java.lang.String)
setOwner(java.lang.String)

 

리소스 경로 얻기

Class 객체는 클래스 파일(*.class)의 경로 정보를 가지고 있기 때문에  이 경로를 기준으로 상대 경로에 있는 다른 리소스 파일(이미지, XML, Property 파일)의 정보를 얻을 수 있다. 이때 사용하는 메서드는 다음과 같다.

메서드 용도
URL getResource(String name) 리소스 파일의 URL 리턴
InputStream getResourceAsStream(String name) 리소스 파일의 InputStream 리턴

 

다음 예제를 진행하기 전 ch12 패키지에 photo1.jpg와 photo2.jpg 파일을 붙여 넣기하고 진행한다.

 

예제 코드

Car.java

package ch12;

public class Car {
}

 

GetResourceExample.java

package ch12;

public class GetResourceExample {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Class clazz = Car.class;
		
		String photo1Path = clazz.getResource("photo1.jpg").getPath();
		String photo2Path = clazz.getResource("photo2.jpg").getPath();
		
		System.out.println(photo1Path);
		System.out.println(photo2Path);
	}

}

 

출력 결과

/C:/Users/%ed%95%99%ec%83%9d/eclipse-workspace/javaclass/bin/ch12/photo1.jpg
/C:/Users/%ed%95%99%ec%83%9d/eclipse-workspace/javaclass/bin/ch12/photo2.jpg

 

 

'Language > JAVA' 카테고리의 다른 글

[JAVA] 제네릭  (0) 2024.10.16
[JAVA] 어노테이션  (1) 2024.10.16
[JAVA] 정규 표현식 클래스  (1) 2024.10.16
[JAVA] 형식 클래스  (0) 2024.10.16
[JAVA] 날짜와 시간 클래스  (0) 2024.10.16