动态代码执行

时间:2010-11-12 15:27:03

标签: java

与动态SQL类似,其中String在运行时作为SQL执行,我们可以动态运行Java代码吗?就像我返回一个字符串,它是一个Java代码,然后我在运行时执行。这可能吗?

7 个答案:

答案 0 :(得分:15)

对于真正的Java代码,可以使用JavaCompiler接口。但是,它使用起来非常不方便,因为它只是一个真正的Java编译器的接口,它希望编译文件中的整个类定义。

执行运行时提供的代码的最简单方法是使用Rhino JavaScript engine

这两个选项都只在Java 6中使用,但我相信之前存在脚本界面,所以如果你下载并将它添加到类路径中,你可以在早期的JRE中使用Rhino。

答案 1 :(得分:6)

了Javassist

您需要使用字节码操作库,例如JavassistWikipedia),以便运行在运行时提供的任意字符串。 Javassist允许您基于表示源代码的字符串创建CtClass;然后可以通过特定的类加载器将其转换为已编译的Class对象,以便该类可供您的应用程序使用。其他库需要做类似于这两个步骤的事情才能实现同样的目的。

所以它有可能,但它非常重量级,很可能会使你的应用程序很难推理。如果可能的话,考虑静态地设计一个非常灵活的类,并让它接受控制其行为的参数。

答案 2 :(得分:4)

如果您想做的不仅仅是动态调用现有方法,您可能需要将String编译为字节码。一个简单的方法是在类路径中包含Eclipse / JDT编译器jar,然后你可以使用它将String编译成一个Class,然后可以加载它。

这种类型的动态代码生成和执行用于将JSP文件转换为Servlet,并在其他包(如JasperReports)中用于将报表规范转换为随后调用的类。

请记住,就像使用SQL一样,如果任何String包含用户指定的数据,则必须小心防止代码注入安全问题。

答案 3 :(得分:4)

您还可以查看Java 6脚本支持: http://download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm

这是一个hello world版本,它创建字符串数组并打印第一个字符串:


import javax.script.*;
public class EvalScript { 
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
        engine.eval("var a=java.lang.reflect.Array.newInstance(java.lang.String, 1);a[0]='Hello World';print(a[0])");
    }
}

答案 4 :(得分:3)

看看Beanshell。它提供了一个类似java语法的解释器。

答案 5 :(得分:3)

是的,这是可能的。查看Java Compiler API。看看这里:

http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html

答案 6 :(得分:-2)

是使用反射:tutorial

另一个来自IBM

的教程