2011-03-04 49 views
6

現在我執行以下操作:你可以強制Java對象在運行時實現接口嗎?

1)的Java接口。

2)的具體的java的類,它不實現上述接口,但確實包含方法簽名的接口中定義的方法中的每一個匹配。

既然我無法改變第2項的執行情況,我想知道是否有可能使接受第1項的實例作爲參數接受第2項無類轉換異常的方法。

感覺就像織各種/強制/ AOP在Spring機制應該做到這一點,但我不知道該怎麼做。

有沒有辦法做到這一點?

+2

難道你不能只製作一個實現接口並轉發所有內容的包裝? – Erik 2011-03-04 17:13:21

+0

包裝的+1 – 2011-03-04 17:15:51

+0

有沒有人知道是否有這種模式的名稱(OP想要什麼),在哪裏「鑄造」具有匹配簽名的對象到接口? – 2017-04-11 11:57:09

回答

7

可以強制Java對象爲實現在運行時的界面?

是的,使用dynamic proxies或字節碼重寫。不過,對我來說,你似乎在尋找Adapter pattern

+0

你有鏈接到任何文檔如何做到這一點,最好是聲明? – dskiles 2011-03-04 17:14:54

+0

@dskiles,使用代理,請參見['Java動態代理 - 如何引用具體類'](http://stackoverflow.com/questions/5167185/java-dynamic-proxy-how-reference-concrete-class/5167267#5167267 )。對於AoP方法,請查看[aspectj](http://www.eclipse.org/aspectj/)或[cglib](http://cglib.sourceforge.net/)項目。 – 2011-03-04 17:28:19

+0

+1 - 很好的建議。 – Nilesh 2011-03-04 18:30:35

3

你不能讓對象本身實現接口,但你可以使用像Proxy這樣的東西來創建一個對象,它實現接口並使用反射來調用原始對象上的相應成員。

當然,如果它只是一個接口類型和一個具體的類型,你可以很容易地寫出這樣的包裝不使用代理服務器:

public class BarWrapper implements Foo 
{ 
    private final Bar bar; 

    public BarWrapper(Bar bar) 
    { 
     this.bar = bar; 
    } 

    public int someMethodInFoo() 
    { 
     return bar.someMethodInFoo(); 
    } 

    // etc 
} 
0

基本上有兩種方式:

一)寫在你的對象一個裝飾實現接口和委託給你的對象

二)改變字節碼(這可以通過使用代理或通過編寫一個簡單的適配器類來實現)。 Spring AOP不夠強大,但AspectJ編譯器是。它是一行代碼:

declare parents: YourClass implements YourInterface; 

由於您無權訪問類源,您將不得不使用加載時編織或編織庫jar。所有這一切都在AspectJ in ActionRamnivas Laddad

1

很好地解釋這應該是可以解決的一個適配器。 定義的其他類,它實現你的接口,並委託給真正的對象:

class YourAdapter implements YourInterface { 

    private final YourClass realObject; 

    public YourAdapter(YourClass realObject) { 
     this.realObject = realObject; 
    } 

    @Override 
    public methodFromInterface() { 
     // you said the class has the same method signatures although it doesn't 
     // implement the interface, so this should work fine: 
     realObject.methodFromInterface(); 
    } 

    // ....... 

} 

。現在,因爲預計YourInterface的方法和YourClass類型的對象:

void someMethod(YourInterface param) {} 

void test() { 
    YourClass object = getFromSomewhere(); 
    someMethod(YourAdapter(object)); 
} 
+0

這就是我現在使用的地方,但如果可能的話,我希望跳過適配器步驟。 – dskiles 2011-03-04 17:20:22

+0

然後,如果您不介意反思,那麼您需要使用其他答案中提到的代理方法。 – 2011-03-04 17:23:55

0

你也許可以做到你想要什麼Javassist,通過修改類的字節碼或創建一個包裝/代理類。

相關問題