2012-01-22 57 views
3

我想創建一個類的對象,並重寫它的一些方法。例如:如何覆蓋用ClassLoader實例化的類的方法

Foo bar = new Foo(){ 

    public void fighters(){ 
      //some stuff 
    } 

}; 

問題是:類的名稱存儲在字符串中。 我顯然此舉是爲了創建一個使用Constructor.newInstance(對象o)方法的新實例,就像這樣:

Class c = cl.loadClass("com.pom.Foo"); 
Foo f = (Foo) (c.getDeclaredConstructor(String.class).newInstance("Hello!")); 

雖然這段代碼成功創建該類的一個新實例,我不知道如何重寫它的方法。

有什麼建議嗎?

+2

爲什麼你不能只創建一個覆蓋方法,編譯它,並實例化這個類而不是Foo的類? –

+0

Java是一種靜態編譯語言,你不能做這種事情。工作錯誤的工具。 – skaffman

+0

@skaffman:這不太正確。你可以做運行時代碼注入(比如像BCEL這樣的東西)。 (不要說你應該,只要你可以。) – Mat

回答

2

我認爲你有幾個選擇,沒有一個很好,而且所有的臭味都與建築問題的高級天堂有關,你如何解決你提出的問題。

委派包裝

創建DelegaingFoo類,看起來像這樣:

class DelegatingFoo { 

    Callable callMe; 

    public DelegatingFoo(Callable callMe) { 
     this.callMe = callMe; 
    } 

    public void fighters(){ 
      calLMe.call(); 
    } 

}; 

實例化這個代替,傳遞Callable對象到構造函數中你是以上。這會使您想要從注入它的位運行的代碼不相交。

使用JVM語言

編譯的東西,可以通過的javax.script,如BeanShell中,Groovy中,等運行取決於你最終做什麼,這可能是一個可行的選項。

自定義類加載器

如果你有使用其他類加載器(其中提出了它自己的問題),這是一件好事,這將是充滿了它自己的問題,並創造的東西確實挺複雜的選項。如果你決定認真考慮這個問題,那麼看起來像OSGi類加載框架可能會給你一些線索(它甚至可能在一定程度上適合)。

字節碼操作

有幾個庫,這將使字節碼改寫(munging)/攔截/生成/改變有助於對飛:

警告

應當指出的是,上述所有的黑客,以作爲你去他們增加墮落。我會盡快讓我的架構同儕審查,因爲我會把錢放在更清晰的方法來處理您正在做的事情。

請記住,您編寫的代碼應該更易於閱讀 - 否則您將爲自己(或未來的項目所有者)創建維護難題。

+0

謝謝大家。 @brainzzy感謝您的詳細回覆。委託類的想法是一個非常好的。 – divs1210

+0

我仍然建議您對整個架構進行更廣泛的審查!無論如何,祝你好運。 –