programing tip

Java Reflection : 구현 클래스 만들기

itbloger 2020. 11. 11. 08:12
반응형

Java Reflection : 구현 클래스 만들기


Class someInterface = Class.fromName("some.package.SomeInterface");

이제 구현하는 새 클래스를 어떻게 만듭니 someInterface까?

새 클래스를 만들고를 SomeInterface인수로 필요한 함수에 전달해야합니다 .


즉석에서 인터페이스를 구현하는 것처럼 가장하는 것을 만드는 것은 실제로 그리 어렵지 않습니다. java.lang.reflect.Proxy구현 후 InvocationHandler모든 메서드 호출을 처리 할 수 있습니다 .

물론 BCEL 과 같은 라이브러리로 실제 클래스를 생성 할 수 있습니다.

이것이 테스트 목적이라면 jMockEasyMock같은 모의 프레임 워크를 살펴 봐야 합니다.


쉽게 java.lang.reflect.Proxy구출!

전체 작업 예 :

interface IRobot {

    String Name();

    String Name(String title);

    void Talk();

    void Talk(String stuff);

    void Talk(int stuff);

    void Talk(String stuff, int more_stuff);

    void Talk(int stuff, int more_stuff);

    void Talk(int stuff, String more_stuff);
}

public class ProxyTest {
    public static void main(String args[]) {
        IRobot robot = (IRobot) java.lang.reflect.Proxy.newProxyInstance(
                IRobot.class.getClassLoader(),
                new java.lang.Class[] { IRobot.class },
                new java.lang.reflect.InvocationHandler() {

            @Override
            public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws java.lang.Throwable {
                String method_name = method.getName();
                Class<?>[] classes = method.getParameterTypes();

                if (method_name.equals("Name")) {
                    if (args == null) {
                        return "Mr IRobot";
                    } else {
                        return args[0] + " IRobot";
                    }
                } else if (method_name.equals("Talk")) {
                    switch (classes.length) {
                        case 0:
                            System.out.println("Hello");
                            break;
                        case 1:
                            if (classes[0] == int.class) {
                                System.out.println("Hi. Int: " + args[0]);
                            } else {
                                System.out.println("Hi. String: " + args[0]);
                            }
                            break;
                        case 2:
                            if (classes[0] == String.class) {
                                System.out.println("Hi. String: " + args[0] + ". Int: " + args[1]);
                            } else {
                                if (classes[1] == String.class) {
                                    System.out.println("Hi. int: " + args[0] + ". String: " + args[1]);
                                } else {
                                    System.out.println("Hi. int: " + args[0] + ". Int: " + args[1]);
                                }
                            }
                            break;
                    }
                }
                return null;
            }
        });

        System.out.println(robot.Name());
        System.out.println(robot.Name("Dr"));
        robot.Talk();
        robot.Talk("stuff");
        robot.Talk(100);
        robot.Talk("stuff", 200);
        robot.Talk(300, 400);
        robot.Talk(500, "stuff");
    }
}

If you want to go beyond interfaces, you might want to take a look at cglib and objenesis. Together, they will allow you to do some pretty powerful stuff, extending an abstract class and instantiating it. (jMock uses them for that purpose, for example.)

If you want to stick with interfaces, do what Jon Skeet said :).


Actually, you have to use the class name in Class.fromName() method and cast to your interface type. See if the sample below helps.

public class Main {

    public static void main(String[] args) throws Exception {
        Car ferrari = (Car) Class.forName("Mercedez").newInstance();
        System.out.println(ferrari.getName());
    }
}

interface Car {
    String getName();
}

class Mercedez implements Car {

    @Override
    public String getName() {
        return "Mercedez";
    }

}

class Ferrari implements Car {

    @Override
    public String getName() {
        return "Ferrari";
    }

}

참고URL : https://stackoverflow.com/questions/1082850/java-reflection-create-an-implementing-class

반응형