**자바 리플렉션(Java Reflection)**은 프로그램이 **런타임(runtime)**에 클래스, 메소드, 필드 등의 구조를 분석하고 제어할 수 있는 기능입니다. 즉, 컴파일 시점이 아니라 실행 중에 객체의 정보를 조회하거나 동적으로 조작할 수 있는 기술입니다.
리플렉션이란?
• 정적(Static) 방식: 일반적으로 자바 프로그램은 코드를 작성할 때 사용할 클래스, 메소드, 필드 등을 명확히 알고 있어야 합니다. 예: String str = new String();
• 리플렉션: 프로그램 실행 중에 동적으로 클래스 이름, 메소드 이름 등을 기반으로 객체를 생성하거나 메소드를 호출합니다.
리플렉션으로 가능한 작업
1. 클래스 정보 얻기
• 클래스 이름, 패키지, 부모 클래스, 구현한 인터페이스 등을 조회 가능.
2. 필드, 메소드 정보 얻기
• 클래스의 변수(필드), 메소드 이름과 타입, 접근제어자 등을 조회 가능.
3. 동적 호출
• 특정 클래스의 객체를 생성하거나 메소드를 실행할 수 있음.
주요 클래스 및 메소드
리플렉션은 java.lang.reflect 패키지에서 제공됩니다.
1. Class 클래스
• 자바에서 모든 클래스는 JVM에서 Class 객체로 표현됩니다.
• Class 객체를 사용해 해당 클래스의 정보를 조회할 수 있습니다.
Class<?> clazz = Class.forName("java.lang.String"); // 클래스 이름으로 가져오기
2. Field 클래스
• 클래스의 멤버 변수(필드) 정보를 조회하거나 값을 수정할 수 있습니다.
Field field = clazz.getDeclaredField("value"); // "value"라는 필드 조회
field.setAccessible(true); // private 필드 접근 가능
3. Method 클래스
• 메소드 정보를 조회하거나 동적으로 호출할 수 있습니다.
Method method = clazz.getMethod("toUpperCase"); // toUpperCase 메소드 조회
Object result = method.invoke("hello"); // 메소드 호출
4. Constructor 클래스
• 생성자 정보를 조회하거나 객체를 동적으로 생성할 수 있습니다.
Constructor<?> constructor = clazz.getConstructor(String.class);
Object obj = constructor.newInstance("Hello");
리플렉션 예제
다음은 리플렉션을 사용하는 간단한 예제입니다.
1. 클래스 정보 조회
public class Test {
private String name;
public void sayHello() {
System.out.println("Hello!");
}
}
// 실행 코드
Class<?> clazz = Test.class;
System.out.println("클래스 이름: " + clazz.getName()); // 클래스 이름
2. 필드 접근 및 값 변경
Test test = new Test();
Field field = Test.class.getDeclaredField("name");
field.setAccessible(true); // private 필드 접근 가능
field.set(test, "Reflection!"); // 필드 값 설정
System.out.println("필드 값: " + field.get(test));
3. 메소드 호출
Test test = new Test();
Method method = Test.class.getMethod("sayHello");
method.invoke(test); // 메소드 동적 호출
리플렉션의 장점
1. 동적 로딩 가능
• 런타임에 필요한 클래스나 메소드를 동적으로 불러올 수 있음.
(예: 플러그인 시스템, ORM 프레임워크 등에서 사용)
2. 범용성
• 사전에 정의된 클래스 구조에 의존하지 않고, 런타임에 유연하게 동작.
3. 검증 및 디버깅
• 클래스 구조를 분석하거나 필드, 메소드 정보를 디버깅에 활용 가능.
리플렉션의 단점
1. 성능 저하
• 리플렉션은 일반적인 코드보다 느립니다. (런타임 해석 과정 때문)
2. 안전성 문제
• private 필드나 메소드에 접근할 수 있어 캡슐화를 깨뜨릴 위험이 있음.
3. 복잡성 증가
• 코드가 더 복잡해지고 가독성이 떨어질 수 있음.
리플렉션의 실제 사용 예시
1. 스프링 프레임워크
• 의존성 주입(Dependency Injection)이나 Bean 관리에서 리플렉션 활용.
2. JUnit
• 테스트 실행 시, 메소드 이름만으로 테스트 메소드를 동적으로 호출.
3. ORM (Hibernate 등)
• 클래스의 필드와 데이터베이스 컬럼 매핑에서 사용.
리플렉션은 강력한 도구지만 남용하면 성능 및 유지보수 문제를 초래할 수 있으니 필요한 상황에서만 사용하는 것이 좋습니다.