백엔드 개발자라면 대답해야 할 100가지 질문

17. 자바 리플렉션(reflection)이란 무엇인가?

ignuy 2023. 9. 26.

자바 가상 머신(JVM)은 클래스 정보를 클래스 로더를 통해 읽어와 해당 정보를 JVM 메모리에 올린다. 해당 클래스의 정보를 담은 Class 타입의 객체를 생성하여 메모리의 Heap 영역에 저장해 두게 된다.

ava에서는 이렇게 만들어진 Class 타입의 객체를 통해 구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 하는 자바 API를 제공하게 된다. 저장된 클래스 정보는 마치 클래스를 거울 앞에 데려가 그 모습을 보여주는 것과 닮아, Reflection이라는 이름을 가지게 되었다.

한가지 특이한 점은 리플렉션은 접근 제어자와는 무관하게 클래스의 필드나 메서드를 호출할 수도 있다.

자바에 그런 것도 있었나?

사실 알게 모르게 우리는 Reflection을 사용하고 있었다. Reflection의 대표적인 예시가 다수의 라이브러리, 프레임워크에서 사용되고 있는 Annotation이 리플렉션을 활용하는 예시이다. 리플렉션을 사용하면 클래스와 메서드에 어떤 Annotation이 붙어 있는지 확인할 수 있다.

사실, Annotation 그 자체로는 아무런 기능을 하지 않지만 리플렉션 덕분에 스프링 빈(Bean)이니, 웹 서블렛(WebServlet)이니, 이런 기능을 사용할 수 있는 것이다.

Class 클래스

리플렉션의 핵심은 Class 클래스이다.

자바는 모든 클래스와 인터페이스를 컴파일 후에 .class 파일로 보관한다. 이 파일에는 객체의 정보가 포함되어 있는데 Class 클래스는 이 .class 파일에 들어있는 객체 정보를 가져올 수 있다.

Class 객체를 통해서 가져올 수 있는 객체 정보는 크게 네가지이다.

💡 1. 필드 변수
💡 2. 메서드
💡 3. 어노테이션

더 자세한 내용은 아래 URL을 참고해 주길 바란다.

자바 리플렉션 (Reflection) 기초

이걸 어디에 쓰지?

리플렉션 특성상 컴파일 시에 동작하지 않고 런타임시에 클래스에 접근한다. Runtime 시점에서 사용할 Instance를 선택하고 동작시킬 수 있는 유연성을 확보하게 된다.

이런 특징은 웹 애플리케이션을 개발하는 상황보단 라이브러리, 프레임워크, 시스템 개발에 사용될 일이 많다. 일반적인 웹 애플리케이션에서 리플렉션을 사용해야 한다면 정말 한정적인 부분에 대해서만 사용하여야 한다.

치명적 단점?

흔히들 Reflection API가 느리고 high cost라고 말한다. Runtime시에 동작하는 특성 때문에 JVM 최적화가 불가능하여 Class가 동적으로 JVM 메모리로 Load 되고 Heap에 객체를 띄우는 과정에서 오버헤드를 심하게 잡아먹기 때문이다.

하지만 이는 엄밀히 말해서 동적으로 Class가 메모리에 올라가는 과정에서 발생하는 오버헤드이지 Reflection이 수행될 때 잡아먹히는 오버헤드가 아니다. 초기 호출 이후로 캐싱을 통해 Reflection API를 통한 메서드 호출을 최적화하게 되면 API 호출에 드는 비용은 줄어들게 된다.

이 외에도 몇 가지 단점이 존재한다.

Runtime시에 동작한다는 특징 때문에 Type이나 Exception에 대한 검증이 불가능하다. 또한 특정 로직의 동작 흐름을 파악하기 어렵다. 기존에 접근 제어자로 캡슐화해놓은 필드, 메서드에도 임의로 접근이 가능하기 때문에 객체 지향의 3요소(캡슐화, 추상화, 상속)마저 부숴버린다.

댓글