2009-07-04 47 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"); 
    } 
}