자바에서 런타임시 클래스의 정보를 분석하고 조작하는 기법으로 컴파일 타임에는 알 수 없는 클래스를 동적으로 로딩하여 사용하거나, 클래스의 메소드, 필드, 생성자 등의 정보를 동적으로 분석할 수 있는 강력한 기능 제공
- 자바에서 이미 로딩이 완료된 클래스에서 또는 다른 클래스를 동적으로 로딩하여 구체적인 타입을 알지 못하더라도 생성자, 멤버 필드, 그리고 멤버 메소드를 사용할 수 있는 기법이다.
객체를 통해서
클래스의 패키지 정보, 접근 지정자, 부모 클래스, 어노테이션 등을 얻을 수 있다.- 즉, 핵심은 컴파일 타임이 아니라 런타임에 동적으로 컴파일 타임에는 알 수 없는 클래스를 특정 클래스의 정보를 객체화하여 분석 및 추출해낼 수 있는 동적 프로그래밍 기법이다.
런타임(Runtime)
은 프로그램이 실행되고 있는 동안의 시간을 가리킨다. 자바에서 런타임은 프로그램이 메모리에 로드되어 실행되고 있는 상태를 의미하며, 여기서 런타임은 컴파일 시간과는 대조되며, 컴파일 시간
은 소스 코드가 기계어 코드로 변환되는 시간을 의미한다.
자바 프로그램은 크게 두 단계로 나뉜다.
따라서 런타임
이라는 용어는 프로그램이 실행되고 있는 동안의 시간 동안에 해당하는 모든 활동을 나타내며, 자바에서 런타임은 JVM이 자바 프로그램을 실행하는 동안의 상태와 활동을 가리킨다.
특히 프레임워크, 라이브러리, 코드 생성 도구 등에서 활용되며, 예를 들어 의존성 주입(Dependency Injection), 객체 직렬화(Serialization), 테스트 프레임워크 등에서 Reflection이 사용
- 동적 클래스 로딩: 프로그램이 실행 중에 동적으로 클래스를 로딩할 수 있다. 이는 특정 클래스의 이름을 문자열로 받아 해당 클래스를 동적으로 로딩하여 인스턴스를 생성할 수 있다.
- 런타임에서의 동적 분석: Reflection을 사용하면 객체의 클래스, 필드, 메소드 등의 정보를 동적으로 분석할 수 있다. 이는 유연하게 객체를 다루고 동적으로 상호작용할 수 있도록 한다.
- 프레임워크와 라이브러리 개발: 많은 프레임워크와 라이브러리는 Reflection을 사용하여 외부에서 제공된 클래스를 동적으로 조작하여 일반적인 동작을 수행하게 된다. 예를 들어, 자동화된 매핑, 직렬화, 그리고 테스트 프레임워크 등이 Reflection을 사용한다.
Class<?> clazz = Class.forName("com.example.MyClass");
Constructor<?> constructor = clazz.getConstructor(Dependency.class);
Object instance = constructor.newInstance(new Dependency());
Class<?> testClass = MyTestCase.class;
for (Method method : testClass.getDeclaredMethods()) {
if (method.isAnnotationPresent(Test.class)) {
method.invoke(testClass.newInstance());
}
}
Class<?> myClass = MyClass.class;
// 클래스의 모든 메소드 가져오기
Method[] methods = myClass.getDeclaredMethods();
// 클래스의 필드 가져오기
Field[] fields = myClass.getDeclaredFields();
Class<?> beanClass = MyBean.class;
Object beanInstance = beanClass.newInstance();
// 빈 등록
applicationContext.registerBean(MyBean.class, () -> beanInstance);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.ser"));
oos.writeObject(new MySerializableObject());
private
멤버에 접근이 가능하므로, 보안에 민감한 부분에서는 조심해야 한다. setAccessible(true)
메소드를 통해 접근 권한을 무시할 수 있기 때문에 신뢰할 수 없는 데이터로부터 Reflection을 사용하는 경우 주의가 필요하다.Reflection은 특별한 상황에서 강력한 기능을 제공하지만, 성능 및 타입 안정성 등의 측면에서 조심해서 사용해야 한다. 코드의 가독성과 유지보수성을 위해서는 Reflection 사용을 최소화하고, 필요한 경우에만 사용하는 것이 좋다.