2012-10-30 178 views
1

我想做Java中的以下內容:Java的動態實現抽象方法

我有一個字符串(任何地方1和10 000)的集合,每個字符串包含不同的方法體(都寫在Java代碼中)爲同一個類的抽象方法。 例如:

string1= "int a=1;" 
string2="System.out.println(\"HelloWorld\");" 
... 

每個字符串可能是以下的抽象方法的實現:

abstract class FOO{ 
    public abstract void doSomething(); 
} 

對於每一個我想產生FOO的實例使用字符串。

我不太知道什麼是最好的方式去: 我在網上搜索,並用這些建議提出了:

  • 使用Java編譯器6 API生成的.class文件和加載它們
  • 使用字節碼操作庫像CGLIB,修改編譯代碼

是否有任何其他建議,因爲這些看起來有點複雜(至少我)......

感謝您的幫助

編輯:

我可能會去我的問題的錯誤的方式。下面是我最終想要實現:

我有代表在一棵樹上

public interface Node{ 
    public <T> void process(T input); 

/* ...其他方法不相關的我的問題... */ 一個節點的接口}

當您向節點提供T的實例時,它會執行某些操作(有些可能需要訪問節點的其他方法),並將其傳遞給子節點。

問題是(程序規範):程序從文本文件中讀取和構建節點,其中包括方法體(這些體在java中)。然後構建樹並返回它。

我覺得要做到這一點,我必須以某種方式爲文本文件中提供的每種方法生成Node的實現。我可能是錯的,而且有可能是一個更好的辦法...

+3

還有其他**,甚至mo重複**選項。 Java不是一種解釋型語言,所以這不能輕易完成。 –

+2

爲什麼你有多達10,000個方法體作爲文本?爲什麼不把它們作爲編譯代碼? –

+1

這可能是一個合法的問題,但** ......我認爲真正的問題發生在包含代碼的「字符串集合」起源之前的某個時間軸上。 – phineas

回答

3

也許你想要的是BeanShell

的BeanShell是一個小型,免費,嵌入式Java源碼解釋與對象腳本語言特徵在Java中。 BeanShell動態執行標準的Java語法,並通過常見的腳本方便擴展它,比如鬆散類型,命令和方法閉包,如Perl和JavaScript中的那些。

您可以交互地使用BeanShell進行Java實驗和調試,並以新方式擴展您的應用程序。腳本Java適用於各種各樣的應用程序,包括快速原型設計,用戶腳本擴展,規則引擎,配置,測試,動態部署,嵌入式系統甚至Java教育。

BeanShell體積小且可嵌入,因此您可以從Java應用程序中調用BeanShell以在運行時動態執行Java代碼或在應用程序中提供可擴展性。或者,您可以使用獨立的BeanShell腳本來操作Java應用程序;動態使用Java對象和API。由於BeanShell是用Java編寫的,並且與應用程序運行在同一個虛擬機中,因此您可以自由地將「實時」對象的引用傳遞到腳本中並作爲結果返回。

總之,BeanShell是動態解釋的Java,再加上一種腳本語言和靈活的環境,所有這些都包含在一個乾淨的包中。功能

  • 完整的Java語法,Java代碼片段的動態執行

    摘要,以及鬆散類型的Java和其它腳本的便利。

  • 透明地訪問所有Java對象和API。
  • 以四種模式運行:命令行,控制檯,小程序,遠程會話服務器。
  • 可以在安全受限的環境中工作,而不需要爲大多數功能生成類加載器或字節碼。
  • 翻譯器是小〜150K的jar文件。
  • 純Java。
  • 它是免費的!

另一種方法是使用一個庫我寫包裝了編譯器API,以便它編譯在存儲器中並加載到當前類加載器(默認)

http://sourceforge.net/projects/essence/files/Essence%20Java%20Config.%20Files/Essence%20JCF%201.02/

http://vanillajava.blogspot.co.uk/2010/11/more-uses-for-dynamic-code-in-java.html

// this writes the file to disk only when debugging is enabled. 
CachedCompiler cc = CompilerUtils.DEBUGGING ? 
     new CachedCompiler(new File(parent, "src/test/java"), new File(parent, "target/compiled")) : 
     CompilerUtils.CACHED_COMPILER; 

String text = "generated test " + new Date(); 
Class fooBarTeeClass = cc.loadFromJava("eg.FooBarTee", "package eg;\n" + 
    '\n' + 
    "import eg.components.BarImpl;\n" + 
    "import eg.components.TeeImpl;\n" + 
    "import eg.components.Foo;\n" + 
    '\n' + 
    "public class FooBarTee{\n" + 
    " public final String name;\n" + 
    " public final TeeImpl tee;\n" + 
    " public final BarImpl bar;\n" + 
    " public final BarImpl copy;\n" + 
    " public final Foo foo;\n" + 
    '\n' + 
    " public FooBarTee(String name) {\n" + 
    "  // when viewing this file, ensure it is synchronised with the copy on disk.\n" + 
    "  System.out.println(\"" + text + "\");\n" + 
    "  this.name = name;\n" + 
    '\n' + 
    "  tee = new TeeImpl(\"test\");\n" + 
    '\n' + 
    "  bar = new BarImpl(tee, 55);\n" + 
    '\n' + 
    "  copy = new BarImpl(tee, 555);\n" + 
    '\n' + 
    "  // you should see the current date here after synchronisation.\n" + 
    "  foo = new Foo(bar, copy, \"" + text + "\", 5);\n" + 
    " }\n" + 
    '\n' + 
    " public void start() {\n" + 
    " }\n" + 
    '\n' + 
    " public void stop() {\n" + 
    " }\n" + 
    '\n' + 
    " public void close() {\n" + 
    "  stop();\n" + 
    '\n' + 
    " }\n" + 
    "}\n"); 

// add a debug break point here and step into this method. 
FooBarTee fooBarTee = new FooBarTee("test foo bar tee"); 
Foo foo = fooBarTee.foo; 
assertNotNull(foo); 
assertEquals(text, foo.s); 
+0

從來沒有聽說過它。我無法遵循鏈接 - 在我的辦公室被阻止。你能解釋一下它到底是什麼嗎? –

+0

這個網站看起來過時了。而且自2005年以來,鏈接的JSR處於休眠狀態。這個東西是否可用? – rolve

+0

它超過數十年,被調試器廣泛用於動態評估表達式。 –