Java 反射:创建一个实现类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1082850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:22:28  来源:igfitidea点击:

Java Reflection: Create an implementing class

javareflectioninterface

提问by Isaac Waller

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

How do I now create a new class that implements someInterface?

我现在如何创建一个实现 的新类someInterface

I need to create a new class, and pass it to a function that needs a SomeInterfaceas an argument.

我需要创建一个新类,并将其传递给需要 aSomeInterface作为参数的函数。

采纳答案by Jon Skeet

Creating something which pretends to implement an interface on the fly actually isn't too hard. You can use java.lang.reflect.Proxyafter implementing InvocationHandlerto handle any method calls.

创建一些假装即时实现接口的东西实际上并不太难。您可以java.lang.reflect.Proxy在实现后使用InvocationHandler来处理任何方法调用。

Of course, you could actually generate a real class with a library like BCEL.

当然,您实际上可以使用像BCEL这样的库生成一个真正的类。

If this is for test purposes, you should look at mocking frameworks like jMockand EasyMock.

如果这是出于测试目的,您应该查看jMockEasyMock模拟框架

回答by jqno

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

如果你想超越接口,你可能想看看cglibobjenesis。在一起,它们将允许您做一些非常强大的事情,扩展抽象类并实例化它。(例如,jMock为此目的使用它们。)

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

如果您想坚持使用接口,请按照 Jon Skeet 所说的去做:)。

回答by nandokakimoto

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

实际上,您必须在 Class.fromName() 方法中使用类名并转换为您的接口类型。看看下面的示例是否有帮助。

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";
    }

}

回答by Pacerier

Easily, java.lang.reflect.Proxyto the rescue!

轻松java.lang.reflect.Proxy救命!

Full working example:

完整的工作示例

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");
    }
}