Java ‐ 리플렉션 - thought-corner/Backend-PlayGround GitHub Wiki
클래스와 메타데이터
- 클래스가 제공하는 다양한 정보를 동적으로 분석하고 사용하는 기능을 리플렉션(Reflection)이라고 한다.
- 리플렉션을 통해 얻을 수 있는 정보는 다음과 같다.
- 클래스의 메타데이터 : 클래스 이름, 접근 제어자, 부모 클래스, 구현된 인터페이스 등
- 필드 정보 : 필드의 이름, 타입, 접근 제어자를 확인하고 해당 필드 값을 읽거나 수정
- 메서드 정보 : 메서드 이름, 반환 타입, 매개변수 정보를 확인하고 실행 중에 동적으로 메서드를 호출
- 생성자 정보 : 생성자 매개변수 타입과 개수를 확인하고 동적으로 객체를 생성
리플렉션 장단점 정리
- 프로그램 유연성을 높여준다.
- 런타임에 클래스 정보를 얻거나 객체를 조작할 수 있기 때문에 동적으로 코드를 변경하거나 확장하는 것이 가능하다.
- 하지만 리플렉션의 가장 큰 단점은 성능 저하이다.
- 리플렉션을 사용하면 일반적인 메서드 호출보다 처리 속도가 느려질 수 있다. 왜냐하면 리플렉션은 런타임에 메서드나 필드에 접근하기 위해 추가적인 처리가 필요하기 때문이다.
- 리플렉션 사용 시 주의해야 할 점은 가능한 한 사용을 최소화하고 성능에 민감한 애플리케이션에서는 사용을 피하는 것이 좋다.
결론 : 자바 리플렉션은 유연성과 확장성을 높여주는 것은 맞지만 위와 같은 여러 단점들이 지적 사항으로 꼽힌다. 최대한 사용을 지양하는 방향으로 알고 있자.
리플렉션 사용 시 주의사항
- 리플렉션은 추가적인 처리를 요구하기 때문에 성능 저하를 유발할 수 있다.
- 리플렉션은 프로그램 안정성을 저하시킬 수 있다. 개발자가 의도치 않은 방식으로 내부 구조에 접근할 수 있기 때문에 예상치 못한 에러가 발생할 수 있다.
- 리플렉션을 사용할 때는 보안 문제에 주의해야 한다. 리플렉션을 통해 비공개 멤버에 접근할 수 있기 때문에 보안 취약점으로 인지될 수 있다.
- 리플렉션은 코드 가독성과 유지보수성을 저하시킬 수 있다. 리플렉션을 사용한 코드는 직관적이지 않고, 디버깅이 어려울 수 있기 때문이다.
1. 컴파일 타임의 안전성 포기(Type Safety)
- 리플렉션은
method.invoke("getNmae")라고 잘못 적어도 컴파일이 성공한다.- 하지만 실행 시점에 서버가 터지면서
NoSuchMethodException을 뱉어내는데 이는 운영 환경에서 예측 불가능한 장애를 일으키는 주범이 된다.2. 압도적인 성능 저하(Performance Overhead)
- 추상화 대가 : JVM은 리플렉션 호출 시 메서드 시그니처 확인, 접근 권한 체크, 인자 타입 매칭 등 복잡한 과정을 매번 수행한다.
- 최적화 불가능 : JIT 컴파일러는 리플렉션을 통해 호출되는 코드를 분석하기 어려워 인라이닝같은 강력한 최적화 기법을 적용하지 못한다.
- 단순 호출 대비 적게는 수십 배에서 많게는 수백 배까지 성능 차이가 발생할 수 있다.
3. 캡슐화의 파괴(Encapsulation Violation)
- 리플렉션은 클래스의
private필드나 메서드에도 강제로 접근할 수 있게 해준다.- 내부 구현 노출 : 객체지향의 핵심인 정보 은닉을 완전히 무시하는 행위이다. 이렇게 되면 객체의 불변성이 깨지고 예기치 못한 사이드 이펙트가 발생한다.
4. 코드 가독성과 유지보수의 지옥
- 복잡한 예외 처리 :
InvocationTargetException,IllegalAccessException,NoSuchMethodException등 수많은 체크 예외를 처리해야 한다.- 추적의 어려움 : IDE에서 이 메서드를 어디서 호출하는지 찾으려 해도 리플렉션으로 호출된 곳은 검색이 불가능해 리팩토링 시 코드를 누락할 위험이 크다.