代码之家  ›  专栏  ›  技术社区  ›  Isaac Waller

Java反射:创建一个实现类

  •  63
  • Isaac Waller  · 技术社区  · 17 年前
    Class someInterface = Class.fromName("some.package.SomeInterface");
    

    现在如何创建一个实现 someInterface ?

    我需要创建一个新类,并将其传递给需要 SomeInterface 作为一个论点。

    4 回复  |  直到 10 年前
        1
  •  51
  •   Jon Skeet    17 年前

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

    当然,您可以使用类似于 BCEL .

    如果这是为了测试的目的,您应该看看模拟框架,比如 jMock EasyMock .

        2
  •  71
  •   catch32    10 年前

    容易地, 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");
        }
    }
    
        3
  •  3
  •   jqno    17 年前

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

    如果你想坚持使用接口,那就按照乔恩·斯基特的话去做。

        4
  •  -3
  •   nandokakimoto    17 年前

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