Reflection이란?
- 자바에서 이미 로딩이 완료된 클래스에서 또 다른 클래스를 동적으로 로딩하여 생성자, 맴버 필드, 맴버 메서드 등을 사용할 수 있는 기법이다.
- 클래스의 패키지 정보, 접근 지정자, 슈퍼 클래스, 애노테이션 등을 얻을 수 있다.
- 컴파일 시간이 아니라 런 타임에 동적으로 특정 클래스의 정보를 개체화를 통해 분석 및 추출해낼 수 있는 프로그래밍 기법이다.
- Spring Framework에서 Bean을 등록하고 꺼내올때 사용된다.
new AnnotationConfigApplicationContext(AppConfig.class);
사용 방법
Class c = Class.forName(”클래스 이름”);
Class c = int.class;
Class c = Integer.TYPE; // 자바 원시 타입의 경우
- 클래스의 이름으로부터 인스턴스를 생성할 수 있고, 이를 이용하여 클래스의 정보를 가져올 수 있다.
예제
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Main {
public static class Member {
private String name;
protected int age;
public String hobby;
public Member(String name, int age, String hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
}
public void speak(String message) {
System.out.println("message = " + message);
}
private void secret() {
System.out.println("비밀번호는 1234입니다.");
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
", age=" + age +
", hobby='" + hobby + '\'' +
'}';
}
}
public static void main(String[] args) throws Exception {
Member member = new Member("새우", 27, "개발");
Class<? extends Member> memberClass = member.getClass();
Field[] fields = memberClass.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.get(member));
}
fields[0].set(member, "새우2");
System.out.println(member);
Method speakMethod = memberClass.getDeclaredMethod("speak", String.class);
speakMethod.invoke(member, "리플렉션 테스트");
Method secretMethod = memberClass.getDeclaredMethod("secret");
secretMethod.setAccessible(true);
secretMethod.invoke(member);
}
}
새우
23
개발
Member{name='새우2', age=23, hobby='개발'}
message = 리플렉션 테스트
비밀번호는 1234입니다.
왜 사용할까?
- 실행 시간에 다른 클래스를 동적으로 로딩하여 접근할 때
- 클래스와 멤버 필드 그리고 메서드 등에 관한 정보를 얻어야할 때
- 리플렉션 없이도 완성도 높은 코드를 구현할 수 있지만, 사용한다면 조금 더 유연한 코드를 만들 수 있다.
주의점
- 외부에 공개되지 않는
private
멤버도 Field.setAccessible()
메서드를 true
로 지정하면 접근과 조작이 가능하기 때문에 주의해야 한다.
출저