오늘 개발을 하며 Reflection을 처음 사용해봤다. 공부할 때는 지나가듯 사용해보았지만 실무에서 사용하게 될 줄은 몰랐다. Reflection이 어떻게 동작하는지 궁금해져 해당 내용을 찾아 공부해보았다.
Reflection이란
reflect는 말 그대로 반사한다는 의미이다.
클래스를 직접 조작하는 것이 아니라, 클래스의 반사된 모습인 JVM의 메모리 영역의 정보를 보고 클래스를 검사 및 조작하는 기술을 뜻한다.
다시 말해, 런타임에 클래스와 인터페이스등을 검사하고 조작할수 있는 기능이다. 리플렉션을 통해 가져올 수 있는 정보로는 필드, 메서드, 생성자, Enum, Annotation, 배열, 부모 클래스와 인터페이스 등 다양하다.
*컴파일 타임 vs 런 타임
컴파일 타임 : 컴파일러가 소스 코드를 컴파일해주는 단계 (스냅샷)
런 타임 : 컴파일된 코드를 실제로 실행시키며 외부 링크, 운영체제, 사용자와 상호작용하는 단계 (상호작용)
Reflection 동작 원리
JVM 동작 방식
.java(자바 소스) --컴파일러--> .class(바이트 코드) --클래스 로더가 JVM Runtime Data Areas에 올려준다
그 중 Method Area에 클래스에 어떤 정보들이 있는지 메타 정보를 저장하게 된다 <= JVM의 메모리 영역의 정보
Reflection 사용법 : Class
결국 Reflection은 method area에 저장된 클래스 수준의 메타 정보를 이용하여 클래스와 인터페이스 등을 조작하는 기능이라고 볼 수 있다.
그렇다면 method area에 접근할 수 있어야하는데, 이 때 사용하는 것이 Class 클래스 이다.
메서드 영역의 클래스 및 인터페이스 정보를 가져오는 전용 클래스이다.
Class 생성 방법
// 1. 클래스타입.class
final Class<Myclass> cls1 = Myclass.class;
// 2. 인스턴스.getClass()
final Myclass obj = new Myclass();
final Class<? extends Myclass> cls2 = obj.getClass();
// 3.Class.forName('풀 패키지 경로')
final Class<?> cls3 = Class.forName("src.app.MyClass");
리플렉션 사용시 주의할 점
getXXXs 메소드는 해당 클래스와 상위 클래스에 있는 public 요소들만 가져온다.
getDeclaredXXXs 메소드는 접근 제어자와 상관없이 해당 클래스의 모든 요소를 가져온다. (상위 클래스는 포함 X)
getDeclaredXXXs 메소드를 통해 private 필드 값을 가져오면 될 것 같지만, IllegalAccessException이 발생한다. 꼭 setAccessbie(true)로 접근 허용을 해준 뒤 값을 가져오거나 바꿔야 한다!
또한 리플렉션은 보안에 취약하며 코드 복잡도를 증가시킨다. 성능도 저하시키며 최적화를 방해하기 때문에 주의하여 꼭 필요할 때만 사용해야 한다.
이 포스팅은 [10분 테코톡] 헙크의 자바 Reflection 를 참고하여 작성되었습니다.
'Java' 카테고리의 다른 글
[Java8] 자바에서 제공하는 함수형 인터페이스 (1) | 2024.07.14 |
---|---|
[Java8] 함수형 인터페이스 (0) | 2024.07.13 |
[Java8] Java8 소개 (0) | 2024.07.13 |
[Java] 파라미터를 전달하는 방법 (원시 타입 vs 참조 타입) (0) | 2024.03.19 |
JDK 설치 / 환경변수 JAVA_HOME 설정 (1) | 2023.12.09 |