Java Study
Reflection API in Java
초코너무조코
2025. 1. 22. 20:26
728x90
목차
1. Reflection API란?
- Reflection API: java.lang.reflect 패키지에서 제공되며 클래스, 메서드, 필드, 생성자를 조작할 수 있는 도구.
- 주요 기능
- 클래스 이름과 구조를 런타임에 확인 가능.
- private 필드, 메서드 등 접근 제약을 우회 가능.
- 동적으로 메서드를 호출하거나 필드 값을 설정 가능.
2. 주요 클래스와 인터페이스
2.1 Class<T> 클래스
- 클래스의 메타데이터를 담고 있는 핵심 객체.
- Class.forName("패키지.클래스")로 특정 클래스 정보를 로드할 수 있음.
Class<?> clazz = Class.forName("com.example.MyClass");
- 주요 메서드:
- getName(): 클래스의 전체 이름(패키지 포함)을 반환.
- getSimpleName(): 클래스 이름만 반환.
- getDeclaredFields(): 모든 필드 정보를 배열로 반환.
- getDeclaredMethods(): 클래스의 모든 메서드 정보 반환.
2.2 Field 클래스
- 클래스의 필드(멤버 변수)를 다루는 클래스.
- 필드 값을 읽고 쓰거나, private 필드에도 접근 가능.
Field field = clazz.getDeclaredField("fieldName");
field.setAccessible(true); // private 필드 접근 허용
field.set(instance, "새 값"); // 필드 값 설정
Object value = field.get(instance); // 필드 값 가져오기
2.3 Method 클래스
- 메서드 호출을 다루는 클래스.
- private 메서드도 호출 가능하며, 메서드의 시그니처에 맞는 인자를 전달해야 함.
Method method = clazz.getDeclaredMethod("methodName", String.class);
method.setAccessible(true); // private 메서드 접근 허용
Object result = method.invoke(instance, "파라미터 값"); // 메서드 호출
2.4 Constructor 클래스
- 생성자 호출을 다루는 클래스.
- 파라미터가 있는 생성자나 private 생성자에도 접근 가능.
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
Object instance = constructor.newInstance("초기값");
3. Reflection 사용 예제
3.1 클래스 정보 가져오기
- 클래스 이름과 부모 클래스 확인.
- 클래스의 메타데이터를 활용하여 동적으로 로드.
Class<?> clazz = String.class;
System.out.println("클래스 이름: " + clazz.getName());
System.out.println("상위 클래스: " + clazz.getSuperclass().getName());
3.2 필드 조작
- private 필드 값을 읽고 수정.
- setAccessible(true)를 사용하여 접근 제한 우회.
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.getDeclaredConstructor().newInstance();
Field field = clazz.getDeclaredField("privateField");
field.setAccessible(true);
field.set(instance, "새 값"); // 필드 값 설정
System.out.println("필드 값: " + field.get(instance));
3.3 메서드 호출
- private 메서드 호출 및 결과 반환.
- 메서드 이름과 파라미터 타입으로 메서드 찾기.
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getDeclaredMethod("privateMethod", String.class);
method.setAccessible(true); // private 접근 허용
Object result = method.invoke(instance, "파라미터 값");
System.out.println("메서드 호출 결과: " + result);
4. 주의사항 및 한계
- 성능 저하: Reflection은 일반 메서드 호출보다 느려 런타임 성능에 영향을 줄 수 있음.
- 캡슐화 위반: private 필드나 메서드에 접근 가능하므로 보안에 민감한 코드에서 주의 필요.
- 런타임 에러: 컴파일 타임 검증 불가로 실행 중에 예외 발생 가능.
5. 사용 사례
- 프레임워크 개발: Spring, Hibernate 등에서 객체 생성과 DI(의존성 주입)에 활용.
- 테스트 도구: JUnit에서 private 메서드나 필드 테스트에 활용.
- 동적 로딩: 런타임에 클래스 이름만으로 기능 구현.
728x90