6.9 KiB
자바 리플렉션(Reflection) 쉽게 배우기
1. 리플렉션이란?
리플렉션(Reflection)이란 실행 중에 클래스의 정보를 조회하고, 필드·메서드·생성자를 동적으로 조작하는 기능이다.
즉, 컴파일 시점이 아니라 런타임(실행 중)에 클래스 내부를 들여다보고 조작할 수 있다.
2. 주요 클래스 및 메서드 정리
(1) Class 클래스 (클래스 정보 조회)
| 메서드 | 설명 |
|---|---|
Class.forName("클래스명") |
클래스 객체 가져오기 (정적 로드) |
Object.getClass() |
인스턴스로부터 클래스 객체 얻기 |
getName() |
클래스 전체 이름 (패키지.클래스명) 반환 |
getSimpleName() |
클래스 단순 이름 반환 |
getDeclaredFields() |
선언된 모든 필드(Field[]) 조회 |
getDeclaredMethods() |
선언된 모든 메서드(Method[]) 조회 |
getDeclaredConstructors() |
선언된 모든 생성자(Constructor[]) 조회 |
예제 코드 (클래스 정보 출력)
Class<?> clazz = Class.forName("java.util.ArrayList");
System.out.println("클래스 이름: " + clazz.getName());
System.out.println("간단한 이름: " + clazz.getSimpleName());
System.out.println("패키지: " + clazz.getPackage().getName());
✅ 클래스의 이름과 패키지 정보를 확인할 수 있다!
(2) Field 클래스 (필드 정보 조회 및 수정)
| 메서드 | 설명 |
|---|---|
getName() |
필드 이름 가져오기 |
getType() |
필드 타입 가져오기 |
getModifiers() |
접근 제어자 가져오기 |
setAccessible(true) |
private 필드 접근 가능하게 설정 |
get(Object obj) |
특정 객체의 필드 값 가져오기 |
set(Object obj, Object value) |
특정 객체의 필드 값 변경 |
예제 코드 (필드 조회 및 값 변경)
import java.lang.reflect.*;
class Person {
private String name = "John";
}
public class ReflectionExample {
public static void main(String[] args) throws Exception {
Person person = new Person();
Class<?> clazz = person.getClass();
Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // private 접근 허용
System.out.println("기존 값: " + field.get(person));
field.set(person, "Alice"); // 값 변경
System.out.println("변경된 값: " + field.get(person));
}
}
✅ private 필드도 강제로 조작할 수 있다!
(3) Method 클래스 (메서드 정보 조회 및 호출)
| 메서드 | 설명 |
|---|---|
getName() |
메서드 이름 가져오기 |
getParameterTypes() |
메서드 매개변수 타입 가져오기 |
getReturnType() |
반환 타입 가져오기 |
invoke(Object obj, Object... args) |
메서드 실행 |
예제 코드 (메서드 실행)
import java.lang.reflect.*;
class Calculator {
private int add(int a, int b) {
return a + b;
}
}
public class ReflectionExample {
public static void main(String[] args) throws Exception {
Calculator calc = new Calculator();
Class<?> clazz = calc.getClass();
Method method = clazz.getDeclaredMethod("add", int.class, int.class);
method.setAccessible(true); // private 접근 허용
int result = (int) method.invoke(calc, 5, 10); // 메서드 실행
System.out.println("결과: " + result);
}
}
✅ private 메서드도 실행할 수 있다!
(4) Constructor 클래스 (생성자 정보 조회 및 인스턴스 생성)
| 메서드 | 설명 |
|---|---|
getParameterTypes() |
생성자 매개변수 타입 가져오기 |
newInstance(Object... initargs) |
새로운 인스턴스 생성 |
예제 코드 (객체 동적 생성)
import java.lang.reflect.*;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class ReflectionExample {
public static void main(String[] args) throws Exception {
Class<?> clazz = Person.class;
Constructor<?> constructor = clazz.getConstructor(String.class);
Object person = constructor.newInstance("Charlie"); // 동적 생성
Method method = clazz.getMethod("getName");
System.out.println("이름: " + method.invoke(person)); // Charlie 출력
}
}
✅ 리플렉션을 이용해 생성자를 실행하고 객체를 만들 수 있다!
(5) Modifier 클래스 (접근 제어자 확인)
| 메서드 | 설명 |
|---|---|
isPublic(int mod) |
public 여부 확인 |
isPrivate(int mod) |
private 여부 확인 |
isStatic(int mod) |
static 여부 확인 |
예제 코드 (필드 접근 제어자 확인)
import java.lang.reflect.*;
class Sample {
private int num;
public static String text;
}
public class ReflectionExample {
public static void main(String[] args) throws Exception {
Field field = Sample.class.getDeclaredField("text");
int modifiers = field.getModifiers();
System.out.println("static인가? " + Modifier.isStatic(modifiers)); // true
System.out.println("public인가? " + Modifier.isPublic(modifiers)); // true
}
}
✅ 필드나 메서드가 public, private, static인지 확인할 수 있다!
3. 리플렉션의 활용 예시
✔ DI(의존성 주입) 프레임워크(Spring) → 리플렉션으로 객체를 생성하고 자동 주입
✔ JUnit 테스트 프레임워크 → @Test 붙은 메서드 자동 실행
✔ JSON 라이브러리(Jackson, Gson) → 객체를 JSON으로 변환할 때 필드 조회
✔ 프록시 패턴(AOP, 동적 프록시) → 런타임에 동적 메서드 실행
4. 리플렉션의 단점과 주의점
❌ 성능 저하 → 리플렉션은 일반 메서드 호출보다 느리다. 자주 사용하면 성능 문제가 생길 수 있다.
❌ 보안 문제 → setAccessible(true)로 private 필드/메서드에 접근할 수 있어 보안 위험이 있다.
❌ 컴파일 타임 체크 불가능 → 오타나 잘못된 메서드 호출은 실행 시점에서야 오류가 발생한다.
✅ 따라서, 꼭 필요한 경우에만 사용하고 남용하지 않는 것이 좋다!
5. 정리
✅ 리플렉션은 실행 중 클래스 정보를 조회하고 조작할 수 있는 기능이다!
✅ Class, Field, Method, Constructor 클래스를 활용하면 필드 값 변경, 메서드 실행, 객체 생성 등이 가능하다!
✅ Spring, JSON 파싱, 테스트 프레임워크 등에서 널리 사용된다!
✅ 하지만 성능 저하와 보안 문제를 고려하여 신중히 사용해야 한다!
✔ 리플렉션을 잘 활용하면, 자바 프로그램을 더 유연하게 만들 수 있다!