【问题标题】:Java Reflection: Create an implementing classJava 反射:创建一个实现类
【发布时间】:2023-03-13 01:56:01
【问题描述】:
Class someInterface = Class.fromName("some.package.SomeInterface");

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

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

【问题讨论】:

标签: java reflection interface


【解决方案1】:

很容易,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");
    }
}

【讨论】:

【解决方案2】:

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

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

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

【讨论】:

  • 哇,太棒了!我想知道 java.lang.reflect 包中还有什么我不知道的?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    实际上,您必须在 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";
        }
    
    }
    

    【讨论】:

    • 这没有抓住问题的关键。 OP 的问题有点不清楚,但他们正在寻找一种在运行时实现类的方法。不仅仅是创建一个未知类的对象,而是完全有效地创建一个新类。
    • 离主题还差得很远
    猜你喜欢
    • 2013-10-26
    • 1970-01-01
    • 2015-03-01
    • 2017-02-21
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    相关资源
    最近更新 更多