Reflection은 클래스의 구체적인 타입을 알지 못해도 크래스의 메소드, 타입, 변수에 동적으로 접근할 수 있게 해주는 API를 말한다. 이를 통해 클래스, 인터페이스, 메소드들을 찾을 수 있고, 객체를 생성하거나 변수를 변경하거나 메소드를 호출할 수 있다. 또한 스프링의 어노테이션도 리플렉션을 이용한 기능이다.
class Person {
int age;
Person() {
this.age = 27;
}
Person(int age) {
this.age = age;
}
int getAge() {
return this.age;
}
}
getDeclaredConstructor()
를 이용해 클래스로부터 인자가 없는 생성자를 가져온다.
Class clazz = Class.forName("Person");
Constructor constructor = clazz.getDeclaredConstructor();
getDeclaredMethods()
를 사용해 클래스로부터 메소드를 가져온다. 그후 invoke()
를 사용하면 메소드 객체를 사용할 수 있다. invoke의 첫번째 인자로는 호출하려는 객체, 두번째 인자는 전달할 파라미터 값을 준다.
Class clazz = Person.class;
Method[] methods = clazz.getDeclaredMethods();
System.out.println(methods[0].invoke(clazz.newInstance())) // 27이 출력됨
getDeclaredFields()
를 사용해 클래스로부터 메소드를 가져온다.
Class clazz = Person.class;
Field[] field = clazz.getDeclaredFields();
System.out.println(field[0]); // 출력 : int reflection_test.Person.age
그 후, set()
메소드를 통해 객체의 변수를 변경할 수 있다.
Class clazz = Person.class;
Field[] field = clazz.getDeclaredFields();
Person person = new Person();
field[0].set(person, 17);
System.out.println(field[0].get(person)); // 17이 출력됨