2009-07-04 51 views
56
Class someInterface = Class.fromName("some.package.SomeInterface"); 

现在我该如何创建一个实现someInterface的新类?Java反思:创建实现类

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

+0

创建对飞类是不容易的,我害怕。 – 2009-07-04 19:44:12

+0

@MichaelMyers这并不难,http://stackoverflow.com/a/9583681/632951 – Pacerier 2012-03-06 12:27:16

回答

46

创建一些假装实现接口的东西其实并不难。执行InvocationHandler后,您可以使用java.lang.reflect.Proxy来处理任何方法调用。

当然,您实际上可以生成一个类库,如BCEL

如果这是出于测试目的,您应该看看嘲笑框架,如jMockEasyMock

+2

哇,整洁!我想知道我不知道java.lang.reflect包中还有什么? – 2009-07-04 20:25:49

2

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

如果您想坚持接口,请执行Jon Skeet所说的:)。

-3

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

} 
+1

这忽略了问题的关键。 OP的问题有点不明确,但他们正在寻找一种在运行时实现类的方法。不是简单地创建一个未知类的对象,而是完全创建一个新类。 – 2012-09-07 19:07:13

63

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