리플렉션(Reflection)이란?
리플렉션의 어원
리플렉션의 어원은 반사, 비치다라는 뜻을 가진다. 즉, 리플랙션은 실질적인 주체(클래스)를 투영한 혹은 반사된 이미지, 클래스 로더에 의해 JVM 메모리 영역에 로드된 클래스 정보를 활용하는 기능이라고 생각해볼 수 있다.
리플렉션이란?
리플렉션은 런타임에 사용되는 기능으로 프로그램 실행 중에 사용자, 운영체제 및 기타 프로그램과 상호작용하면서 클래스, 인터페이스 등을 검사하고 조작할 수 있는 기능을 말한다.
💡
컴파일타임 : 소스코드를 컴파일러에 의해 컴파일 하는 단계 => 스냅샷
런타임 : 컴파일된 코드를 운영체제, 사용자 등과의 상호작용하는 단계 => 상호작용
리플렉션 동작 원리
컴파일된 코드는 Class Loader에 의해 클래스의 메타정보들을 메서드 영역에 저장한다. 이때 리플렉션 개념에서 거울에 반사된 이미지가 바로 JVM 메모리 영역에 저장된 클래스의 메타 정보를 말하는 것이다.
JVM 메모리 영역에 접근하는 방법 : Class 사용하기
여기서 말하는 Class는 개념적인 Class가 아닌 java.lang 패키지에 존재하는 Class의 이름을 가진 클래스를 말한다.
Class는 실행중인 자바 애플리케이션의 클래스와 인터페이스의 정보를 가진 클래스이다. Class는 public 생성자가 존재하지 않고 JVM에 의해 자동으로 객체를 생성한다.
Class 생성 방법
1. 클래스 타입.class
Class<MyClass> c1 = MyClass.class;
2. 인스턴스.getClass()
MyClass obj = new MyClass();
Class<? extends MyClass> c2 = obj.getClass();
3. Class.forName("풀 패키지 경로");
Class<?> c3 = Class.forName("server.app.MyClass");
리플렉션 사용법
리플렉션으로 가져올 수 있는 정보
리플렉션은 JVM 메모리 영역에 저장된 클래스의 내부 정보에 접근할 수 있기 때문에 다양한 정보를 가져올 수 있다.
필드, 메서드, 생성자, Enum, Annotation, 배열, 부모 클래스, 인터페이스 등 다양하다.
필드, 메서드 생성자 값 가져오기
참조 범위 | 접근 제어자 | |
get***s() | 자신과 상위 클래스 | public만 |
getDeclared***s() | 자신 | 모두 |
다만, private 필드일 경우 getDeclared***s()를 사용해도 접근이 불가능하기 때문에 별도의 메서드(setAccessible(true))를 사용해야 한다.
또한, 해당 메서드를 사용하면 private 필드의 값도 변경할 수 있다.
리플렉션의 단점
리플렉션을 사용하면 클래스 정보에 쉽게 접근할 수 있어 마냥 좋을 것 같지만 단점도 존재한다.
1. 성능 저하 : 리플렉션은 메서드나 필드에 접근할 때마다 런타임 검사와 보안 검사가 추가되므로 처리 속도가 저하된다.
2. 안전성 부족(보안 취약) : 컴파일 타임에 타입 안전성 검사를 할 수 없으므로, 잘못된 클래스나 메서드에 접근하는 경우 런타임 예외가 발생할 수 있다.
3. 코드의 복잡성 : 리플렉션을 오용하면 코드가 복잡해질 수 있고, 유지 보수가 어려워진다.
이 외의에 최적화를 방해하는 문제, 타입 안정성, 호환성에 대한 문제가 존재한다.
Reference.
https://youtu.be/RZB7_6sAtC4?si=WuyabbMDwRb_bDyt
'Backend > Java & Kotlin' 카테고리의 다른 글
[JVM]가비지 컬렉션(Garbage Collection, GC)의 작동 원리 (0) | 2023.09.11 |
---|---|
[JVM] 힙(Heap) 영역 (0) | 2023.09.08 |
[JVM]가비지 컬렉션(Garbage Collection, GC)의 개념 (0) | 2023.09.01 |
[JVM] 동작 방식 및 메모리 구조(2) (0) | 2023.08.31 |
[JVM] 동작 방식 및 메모리 구조(1) (0) | 2023.08.30 |