본문 바로가기

IT

자바 리플렉션(reflection)

728x90

자바 리플렉션이란

자바 리플렉션 API(Java Reflection API)는 자바 클래스, 인터페이스, 메서드, 필드 등의 정보를 동적으로 검색하고, 분석하고, 조작할 수 있는 기능을 제공한다. 이를 통해 실행 중인 자바 애플리케이션에서 객체를 조작하거나 클래스의 동적 로딩, 메서드 호출 등을 가능하게 한다.

// 클래스 로딩
Class<?> myClass = Class.forName("com.example.MyClass");

// 객체 생성
Object myObject = myClass.newInstance();

// 메서드 호출
Method myMethod = myClass.getMethod("myMethod", String.class);
myMethod.invoke(myObject, "hello");

// 필드 접근
Field myField = myClass.getField("myField");
myField.set(myObject, "world");

위 코드에서 Class.forName 메서드를 사용하여 동적으로 클래스를 로딩하고, newInstance 메서드를 사용하여 객체를 생성한다. 그리고 getMethod 메서드를 사용하여 메서드를 검색하고, invoke 메서드를 사용하여 해당 메서드를 호출하며getField 메서드를 사용하여 필드를 검색하고, set 메서드를 사용하여 필드 값을 변경할 수 있다.

 

리플렉션 API의 장점

1. 동적으로 객체를 생성하거나 메서드를 호출할 수 있다.
2. 코드 작성 시 클래스 이름을 문자열로 지정하는 것으로 클래스를 로딩할 수 있다.
3. 어떤 클래스의 정보도 동적으로 검색할 수 있다.

 

리플렉션 API의 단점

1. 실행 시간에 추가 오버헤드가 발생한다.
2. 코드가 복잡해질 수 있다.
3. 보안상의 이슈가 있을 수 있다.

스프링의 경우 private 생성자를 가진 클래스를 빈으로 등록해주면 리플렉션을 이용해 객체를 만들어준다. 리플렉션은 private으로 선언된 접근 규약을 위반할 수 있는 강력한 기능이 있다. 하지만 생성자를 private으로 만들었다는 것은 스태틱 메소드를 통해 객체가 만들어져야 한다는 중요한 이유가 있기 무시하고 강제로 생성하면 위험하기에 조심해야한다.

 

리플렉션 API 사용 용도

객체 생성 시 클래스 이름을 동적으로 결정해야 하는 경우, 메서드나 필드의 이름을 동적으로 결정해야 하는 경우 사용하며 주로 프레임워크나 라이브러리에서 사용된다. 

 

리플렉션 API의 대표적인 사용 예시로 스프링 프레임워크가 있다. 스프링의 IoC 컨테이너에서 빈(Bean) 객체를 생성하고, 의존성 주입(Dependency Injection)을 처리하는 데 사용된다. 런타임 시에 동적으로 클래스를 로딩하고 객체를 생성하여 의존성을 주입하는 방식을 사용된다.

또한, 자바 직렬화(Serialization)에서도 리플렉션 API가 사용된다. 직렬화란 객체를 바이트 스트림으로 변환하여 저장하거나 네트워크를 통해 전송할 수 있는 방법입니다. 이 때, 리플렉션 API를 사용하여 객체의 정보를 분석하고 바이트 스트림으로 변환하는 작업을 수행한다.

마지막으로, 리플렉션 API를 사용하여 객체를 동적으로 생성하거나 메서드를 호출하는 것은 테스트 코드 작성 시에 유용하게 사용된다. 예를 들어, JUnit과 같은 테스트 프레임워크에서는 리플렉션 API를 사용하여 테스트 대상 객체를 동적으로 생성하고 테스트 메서드를 호출하는 방식으로 사용한다.