2017-09-14 58 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"); 

處理程序類代表要提供實現:

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

相關問題