학습 목표
- Java reflection이란 무엇인가?
- 언제 사용하는가?
- 장단점
개념
클래스 로더를 통해 static(Method) 영역에 로드된 Class Type의 객체를 통해, 구체적인 Class Type을 알지 못하더라도 해당 Class의 다음과 같은 정보에 접근할 수 있게 한다.
- Method
- Class
- Field
- Constructor
위와 같은 기능 덕분에, 컴파일된 바이트 코드를 통해 Runtime에 동적으로 특정 Class의 정보를 추출할 수 있는 기능을 제공하는 것이 Java Reflection API이다.
언제 사용하는가?
- 동적으로 Class를 사용하는 경우
- Compile time이 아닌, Runtime에 Class를 가져와서 실행해야 하는 경우 (ex : Spring DI)
- 객체 생성, 필드 조작, 메소드 호출
- 클래스의 정보를 탐색하는 경우
- 클래스 이름, Super class, (접근제한자와 상관 없이) 모든 필드, 메소드, 생성자 등
- JSON/XML 등의 데이터로 직렬화/역직렬화 할 때
- 다양한 라이브러리들이 리플렉션을 통해 해당 클래스의 필드와 직렬화된 JSON/XML을 매핑시킨다.
- Proxy 객체
- 다양한 메소드 콜을 intercept하는 프록시 객체를 생성.
- Lazy Loading
- AOP(JDK Dynamic Proxy only)
- AOP 대상을 프록시 객체로 만들기 위해 reflection을 사용하여 구현한다.
장점
- 어플리케이션 내에서가 아닌, 외부 라이브러리/프레임워크가 런타임시에 동작할 때 쓰인다.
- 프레임워크/라이브러리 등에서는 해당 프레임워크/라이브러리가 어디에 쓰일지 모르므로 리플렉션을 이용하여 동적으로 기능을 이용할 수 있도록 한다.
- 실제로 다양한 프레임워크/라이브러리에서 Reflection을 이용한다. (ex : Spring DI, JPA Entity 등)
- 디버깅 시 리플렉션을 이용하여 private field까지도 검사할 수 있다.
단점
- 성능이 떨어진다.
- 동적으로 객체를 생성하므로, JIT Compiler의 최적화를 받지 못한다.
- 매번 명시된 클래스가 맞는지, 적절한 생성자를 이용했는지에 대해서 체크를 해야 한다.
- 캡슐화가 깨진다.
- 리플렉션을 통해 접근제한자 상관없이 모든 필드/메소드를 접근할 수 있으므로.
- Compile-time Safety를 누리지 못한다.
- 런타임 시에 객체가 생성되므로, 컴파일 시점에 누릴 수 있는 type check/Exception check를 이용하지 못한다.
ref