구체적인 클래스 타입을 알지 못해도 해당 클래스의 객체 생성, 메소드, 타입, 변수들에 접근할수 있도록 도와주는 Java API
동적으로 클래스를 사용해야 할때 필요하다. 즉, 작성 시점에는 어떤 클래스를 사용해야 할지 모르는 경우, 런타임 시점에서 클래스를 가져와서 실행해야 하는 경우에 사용된다. 대표적으로 IntelliJ의 자동완성이나 Spring 프레임워크의 어노테이션 같은 기능들이 리플렉션을 이용해서 프로그램 실행 중 동적으로 클래스 정보를 가져와서 사용하는 예이다.
자바 클래스 파일은 프로그램 생성시에 힙영역에 저장된다. 그래서 클래스 이름만 알고 있다면 언제든 이 영역에 들어가서 클래스의 정보를 가져올수 있다.
public class Parent {
public final static int x = 1;
void hi() {
System.out.println("parent hi");
}
public int bye(int x, boolean y) throws IndexOutOfBoundsException {
System.out.println(x + ", " + y);
return 0;
}
}
public class Main extends Parent {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class cls = Class.forName("Parent");
// declae if object is instance of cls
System.out.println(cls.isInstance(new Object()));
System.out.println(cls.isInstance(new Main()));
System.out.println();
// Find class methods
Method[] methList = cls.getDeclaredMethods();
for (Method m : methList) {
System.out.println("method: " + m.getName());
System.out.println("class: " + m.getDeclaringClass());
System.out.println("params");
Parameter[] parList = m.getParameters();
for (Parameter p : parList) {
System.out.println("type: " + p.getType());
System.out.println("name: " + p.getName());
}
Class<?>[] eList = m.getExceptionTypes();
for (Class e : eList) {
System.out.println("exception: " + e);
}
System.out.println("return type = " + m.getReturnType());
System.out.println();
}
// Find class constructors
Constructor[] consts = cls.getDeclaredConstructors();
// Find class fields
Field[] fields = cls.getDeclaredFields();
System.out.println(fields[0].getName() + ", " + fields[0].getType());
System.out.println(Modifier.toString(fields[0].getModifiers()));
// Create new instance
Object[] parList = null;
consts[0].newInstance(parList);
// Run methods by reflection info
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Boolean.TYPE;
Object[] argList = new Object[2];
argList[0] = new Integer(0);
argList[1] = new Boolean(true);
Method m = cls.getMethod("bye", partypes);
m.invoke(consts[0].newInstance(parList), argList);
}
}
실행결과
false
true
method: bye
class: class Parent
params
type: int
name: arg0
type: boolean
name: arg1
exception: class java.lang.IndexOutOfBoundsException
return type = int
method: hi
class: class Parent
params
return type = void
x, int
public static final
0, true