반응형
Reflection이란?
- Runtime 시점에 메모리상의 객체를 조작하는 행위를 말한다.
예제에서 사용할 Reflection 대상 클래스
public class Calculator {
private String name;
public Calculator() {
this("default");
}
public Calculator(String name) {
this.name = name;
}
public int add(int a, int b) {
return a + b;
}
public String getName() {
return name;
}
}
Constructor 목록 가져오기
// Class<?> cls = Class.forName("com.example.Calculator");
Class<?> cls = Calculator.class;
Constructor<?>[] constructors = cls.getDeclaredConstructors();
Assertions.assertEquals("public com.example.Calculator()", constructors[0].toString());
Assertions.assertEquals("public com.example.Calculator(java.lang.String)", constructors[1].toString());
객체 생성하기
Class<?> cls = Calculator.class;
Constructor<?> constructor1 = cls.getDeclaredConstructor();
Constructor<?> constructor2 = cls.getDeclaredConstructor(String.class);
Object calculator1 = constructor1.newInstance();
Object calculator2 = constructor2.newInstance("test");
Assertions.assertEquals("com.example.Calculator", calculator1.getClass().getName());
Assertions.assertEquals("com.example.Calculator", calculator2.getClass().getName());
객체 메소드 실행하기
Class<?> cls = Calculator.class;
Constructor<?> constructor = cls.getDeclaredConstructor();
Object calculator = constructor.newInstance();
Method addMethod = cls.getDeclaredMethod("add", int.class, int.class);
Object result = addMethod.invoke(calculator, 1, 2);
Assertions.assertEquals(3, result);
필드 값 가져오기
Class<?> cls = Calculator.class;
Constructor<?> constructor1 = cls.getDeclaredConstructor();
Constructor<?> constructor2 = cls.getDeclaredConstructor(String.class);
Object calculator1 = constructor1.newInstance();
Object calculator2 = constructor2.newInstance("test");
Field nameField = cls.getDeclaredField("name");
nameField.setAccessible(true);
Assertions.assertEquals("default", nameField.get(calculator1));
Assertions.assertEquals("test", nameField.get(calculator2));
필드 값 변경하기
Class<?> cls = Calculator.class;
Constructor<?> constructor = cls.getDeclaredConstructor();
Object calculator = constructor.newInstance();
Field nameField = cls.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(calculator, "default2");
Assertions.assertEquals("default2", nameField.get(calculator));
인터페이스 구현하기
public interface Calculator {
int add(int a, int b);
}
InvocationHandler handler = (proxy, method, args) -> {
if (method.getName().equals("add")) {
int a = (int) args[0];
int b = (int) args[1];
return a + b;
}
return null;
};
Calculator calculator = (Calculator) Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{Calculator.class}, handler);
int result = calculator.add(1, 5);
Assertions.assertEquals(6, result);
반응형
'Development > Java' 카테고리의 다른 글
[Java] CompletableFuture (0) | 2021.03.30 |
---|---|
[Java] Annotation Processor (0) | 2021.03.04 |
[Java] Simple Machine Learning (0) | 2021.02.27 |
[Java] Regular Expression (0) | 2020.12.28 |
[Java] Thread Dump (0) | 2020.12.28 |