1. 리플렉션이란
만약 자기가 클래스의 존재는 알고 있지만 그것을 사용하고 싶을때,
구체적인 클래스 타입을 알지 못한다면 어떻게 해야할까
리플렉션은 프레임워크에서 많이 쓰인다고 한다.
예를 들어 스프링의 DI를 생각해보자
스프링 같은 프레임워크는 우리가 언제 뭘 쓸지 모른다.
그런데도 우리가 쓰려는 객체를 잘 주입해준다.
이와 같이 클래스 정보를 모를때 동적으로 클래스를 사용하기 위해 만들어진 API를
리플렉션이라 한다.
쓰이는 곳은
- Jackson 이나 GSON 등의 JSON 직렬화 라이브러리
- Log4j2, logback 등의 Logging 관련 프레임워크
- Apache Commons BeanUtils 등의 Class Verfication API
- Spring framework 의 @Autowired와 같은 DL, DI 기능
- IntelliJ 나 Eclipse 등의 IDE
- Junit , hamcrest 등의 test framework
한번 코드로 예시를 봐보자
Class forReflectionClass = Mola.class; //mola 의 클래스를 가져온다.
Field[] fields = forReflectionClass.getDeclaredFields(); // mola 클래스의 모든 필드를 가져온다.
for(final Field field : fields){
System.out.println("필드의 타입 정보 " + field.getType()); //boolean
System.out.println("필드의 이름 정보 " + field.getName()); //someLongLongLongName
}
-----------------------------------------------------------------------------
public class Mola{
//필드가 한개라고 할 때
boolean someLongLongLongName;
//
//
2. 한번 대충 만들어보자
리플렉션의 흐름은 이렇다.
- 1. JVM 의 ClassLoader 는 .class 를 Perm Gen 에 Load한다.
- 2. Class 형식의 Instance가 생성이된다.
- 3. 그럼 Type.class 형식으로 heap에 저장된다.
- 4. SomeClass.class 나 Class.forName("ClassPath") 등으로 접근이 가능하다.
자 그럼 리플렉션을 활용하여 Spring의 Autowired 처럼 객체를 주입하는 코드를 만들어보자
서비스의 흐름은 대충 이런느낌이다.
- 해당 클래스 타입의 기본생성자로 인스턴스 생성
- 클래스의 모든 필드를 불러온다.
- 어노테이션으로 Autowired 가 붙어있는 필드만 선택
- 필드에 맞는 인스턴스를 생성
- 필드의 접근제어자가 private인 경우에 수정가능하게 변경
- 인스턴스에 생성된 필드를 주입
3.주의할 점
- 지나친 사용은 성능 저하를 일으킨다.
- 이미 인스턴스를 만들었음에도 굳이 필드와 리플렉션을 이용해서 접근하거나 사용할 경우
- 컴파일 시에 확인되지 않은데도 런타임 시에만 발생하는 문제를 일으킬 수 있다.
- 접근 지시자도 무시가 가능해서 위험할 수도 있다.
4. 리플렉션의 성능 저하
리플레션 API 는 느리고 비용이 높다고 한다.
그 이유는 Reflection 을 통한 초기 호출 시 JVM이 해당 정보를 미리 최적화 하지 않기 때문이다.
그래도 초기 호출 이후로는 캐싱을 통해 Reflection API를 통한 메서드 호출도 최적화된다.
초기 호출시에는 5배 이상의 차이를 보이더라도 이후 호출로부터는 그러한 간격이 줄어든다
하지만 setAccessible과 같은 class 정보 설정 기능을 사용하는 경우에는 그렇지 않을수도 있다.
참고
자바 reflection oracle documentation
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/package-summary.html
Java 리플렉션 API와 성능 이슈?
https://lob-dev.tistory.com/entry/Java%EC%9D%98-Reflection-API
자바 리플렉션이란?
https://dublin-java.tistory.com/53
'언어 > java' 카테고리의 다른 글
데몬 스레드 (0) | 2021.01.07 |
---|---|
멀티 스레드 (0) | 2021.01.07 |
static에 관한 정리 (0) | 2021.01.04 |
배열 (0) | 2020.12.30 |
comparable 과 comparator (0) | 2020.12.29 |