반응형

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

+ Recent posts