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

someInterfaceを実装する新しいクラスを作成するにはどうすればよいですか?Java Reflection:実装クラスを作成する

私は新しいクラスを作成し、それを引数としてSomeInterfaceを必要とする関数に渡す必要があります。

+0

は、私は怖い、全く簡単ではありません。 –

+0

@MichaelMyersそれほど難しくはありません、http://stackoverflow.com/a/9583681/632951 – Pacerier

答えて

46

実際にインターフェイスを実装しようとするものを作成することは、それほど難しくありません。任意のメソッド呼び出しを処理するためにInvocationHandlerを実装した後にjava.lang.reflect.Proxyを使用できます。

もちろん、BCELのようなライブラリを使って実際のクラスを生成することができます。

テスト目的の場合は、jMockEasyMockのようなモッキングフレームワークを参照する必要があります。

+2

ああ、きちんとしてください!私が知りませんjava.lang.reflectパッケージに他に何が入っているのでしょうか? –

2

インターフェイスを超えたい場合は、cglibobjenesisをご覧ください。一緒に、あなたは、抽象クラスを拡張し、それをインスタンス化する、かなり強力なものを行うことができます。

インターフェイスを固定したい場合は、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の質問は少し不明ですが、実行時にクラスを実装する方法を探しています。単純に不明なクラスのオブジェクトを作成するのではなく、新しいクラスを効率的に作成するだけです。 –

+0

それはトピックの近くにもありません –

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

これはこの回答の良い追加投稿です:http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html – jonashackt

+0

スモーブ..ありがとう。 – kwikness