Java动态实现抽象方法

标签 java dynamic runtime

我正在尝试用 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这样的字节码操作库来修改编译代码

还有其他建议吗,因为这些看起来有点复杂(至少对我自己而言)...

谢谢你的帮助

编辑:

我可能会以错误的方式解决我的问题。这是我最终要实现的目标:

我有一个表示树中节点的接口(interface)

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

/* ...其他与我的问题无关的方法...*/

当您向节点提供 T 的实例时,它会对其执行一些操作(有些可能需要访问 Node 的其他方法),并将其传递给子节点。

问题是(程序的规范):程序从文本文件读取并构建节点,包括方法主体(主体在 java 中)。然后构建树并将其返回。

我的印象是,要做到这一点,我必须以某种方式为文本文件中提供的每个方法生成 Node 的实现。虽然我可能是错的,但可能有更好的方法...

最佳答案

也许你想要的是BeanShell

BeanShell is a small, free, embeddable Java source interpreter with object scripting language features, written in Java. BeanShell dynamically executes standard Java syntax and extends it with common scripting conveniences such as loose types, commands, and method closures like those in Perl and JavaScript.

You can use BeanShell interactively for Java experimentation and debugging as well as to extend your applications in new ways. Scripting Java lends itself to a wide variety of applications including rapid prototyping, user scripting extension, rules engines, configuration, testing, dynamic deployment, embedded systems, and even Java education.

BeanShell is small and embeddable, so you can call BeanShell from your Java applications to execute Java code dynamically at run-time or to provide extensibility in your applications. Alternatively, you can use standalone BeanShell scripts to manipulate Java applications; working with Java objects and APIs dynamically. Since BeanShell is written in Java and runs in the same VM as your application, you can freely pass references to "live" objects into scripts and return them as results.

In short, BeanShell is dynamically interpreted Java, plus a scripting language and flexible environment all rolled into one clean package.

Summary of features

  • Dynamic execution of the full Java syntax, Java code fragments, as well as loosely typed Java and additional scripting conveniences.
  • Transparent access to all Java objects and APIs.
  • Runs in four modes: Command Line, Console, Applet, Remote Session Server.
  • Can work in security constrained environments without a classloader or bytecode generation for most features.
  • The interpreter is small ~150K jar file.
  • Pure Java.
  • It's Free!!

另一种方法是使用我编写的库,它包装了 Compiler 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);

关于Java动态实现抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13139401/

相关文章:

java - 搜索标签,然后将标签之间的文本保存为变量

java - 制作具有三列的响应式 Gridview 图像

c# - 如何将动态复选框设置为真/假

python - 运行时警告 : invalid value encountered in reduce

java进程停止整个进程树

java - 构造函数抛出异常;嵌套异常是 java.lang.NoClassDefFoundError : javax/servlet/ServletContext

java - 哪个 jar 会被加载到 JVM 中?

asp.net - 强类型数据集的动态连接字符串

c# - c# 中的动态对象,其中键具有 $ 符号

ios - 如何知道 visibleViewController 何时更改(Push 和 Model 两者)