我正在尝试在Java中执行以下操作:
我有一个字符串集合(1到10 000之间),每个字符串包含一个不同的方法体(它们用Java代码编写),用于类的相同抽象方法。 例如:
string1= "int a=1;"
string2="System.out.println(\"HelloWorld\");"
...
每个字符串都可以是以下抽象方法的实现:
abstract class FOO{
public abstract void doSomething();
}
对于每个字符串,我想生成一个要使用的FOO实例。
我不太确定最好的方法是什么: 我在网上搜索并提出了这些建议:
还有其他建议,因为这些看起来有点复杂(至少对我自己而言)......
感谢您的帮助
编辑:
我可能会对我的问题采取错误的方式。以下是我最终要实现的目标:
我有一个表示树中节点的接口
public interface Node{
public <T> void process(T input);
/ * ...与我的问题无关的其他方法...... * / }
当你向节点提供T的实例时,它会对它做一些事情(有些可能需要访问Node的其他方法),并将其传递给子节点。
问题是(程序的规范):程序从文本文件中读取和构建节点,包括该方法体(主体在java中)。然后它构建树并返回它。
我的印象是,为了做到这一点,我必须以某种方式为文本文件中提供的每个方法生成Node的实现。我可能错了,可能有更好的方法......
答案 0 :(得分:3)
也许你想要的是BeanShell
BeanShell是一个小型,免费,可嵌入的Java源代码解释器,具有用Java编写的对象脚本语言功能。 BeanShell动态执行标准Java语法,并使用常见的脚本编写方便性扩展它,例如松散类型,命令和方法闭包,如Perl和JavaScript中的那些。
您可以交互式地使用BeanShell进行Java实验和调试,以及以新的方式扩展应用程序。脚本Java适用于各种各样的应用程序,包括快速原型设计,用户脚本扩展,规则引擎,配置,测试,动态部署,嵌入式系统,甚至Java教育。
BeanShell很小且可嵌入,因此您可以从Java应用程序调用BeanShell以在运行时动态执行Java代码或在应用程序中提供可扩展性。或者,您可以使用独立的BeanShell脚本来操作Java应用程序;动态地使用Java对象和API。由于BeanShell是用Java编写的,并且与应用程序在同一个VM中运行,因此您可以自由地将对“实时”对象的引用传递给脚本并将其作为结果返回。
简而言之,BeanShell是动态解释的Java,加上脚本语言和灵活的环境都集成在一个干净的包中。
功能摘要
- 动态执行完整的Java语法,Java代码片段,以及松散类型的Java和其他脚本编写方便。
- 透明访问所有Java对象和API。
- 以四种模式运行:命令行,控制台,小程序,远程会话服务器。
- 可以在安全受限的环境中工作,而无需为大多数功能生成类加载器或字节码。
- 解释器是小~150K jar文件。
- 纯Java。
- 这是免费的!!
另一种方法是使用我编写的库,它包装了编译器API,以便在内存中编译并加载到当前的ClassLoader中(默认情况下)
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);