2017-09-14 12 views
1

リフレクションを使用すると、コンパイル時に使用できないクラスのメソッドへの呼び出しを実装できます。これは、フレームワークコードが異なるライブラリバージョンで動作することを可能にする効果的な方法です。今コンパイル時に使用できないインターフェイスを実装する方法

は、インターフェースがあると言う

interface FutureIntf { 
    method1(String s); 
} 

私のコードは、まだこのインターフェイスを知らないが、私は、このインタフェースは、将来のライブラリのバージョンで利用可能になるかもしれない時間のための実装を準備したいと思いますこのインタフェースの実装で動作する必要があります。私はjavassistを避けたいです。私はjava.lang.reflect.Proxy.newProxyInstanceを使って方法があるべきだと思うが、私はまだそれを効果的にやる方法は分かっていない。

答えて

1

まず、インターフェイスを何とか取得する必要があります。次に、newProxyInstanceで説明したようにプロキシを作成します。最後に、インタフェース上のメソッドを呼び出すか、プロキシをサービスロケータなどにパブリッシュできます。

Class<?> unknownInterface = ClassLoader.getSystemClassLoader().loadClass("bar.UnknownInterface"); 

Object proxy = Proxy.newProxyInstance(unknownInterface.getClassLoader(), 
             new Class[] { unknownInterface }, 
             new Handler()); 

unknownInterface.getMethod("someMethod", String.class).invoke(proxy, "hello"); 
// other way to call it: 
// ((UnknownInterface) proxy).someMethod("hello"); 

Handlerクラスは、あなたが提供したいの実装を表します

public class Handler implements InvocationHandler { 
    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     if (method.getName().equals("someMethod")) { 
      System.out.println("this is the business logic of `someMethod`"); 
      System.out.println("argument: " + args[0]); 
      return null; 
     } 
     return null; 
    } 
} 

の欠点は、ここではどのようなものです:

  • あなたのインタフェースのClassオブジェクトを取得する必要があります。おそらくそれの名前が必要です。
  • a)メソッドの名前とパラメータを知っている必要があります。
  • b)メソッドのパラメータタイプを知っていれば、それらの型と一致させることができます。 this tutorial about proxies

    に基づいてargs.length == 1 && args[0].getClass == String.class

関連する問題