2012-10-30 177 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

它超过数十年,被调试器广泛用于动态评估表达式。 –