与动态SQL类似,其中String在运行时作为SQL执行,我们可以动态运行Java代码吗?就像我返回一个字符串,它是一个Java代码,然后我在运行时执行。这可能吗?
答案 0 :(得分:15)
对于真正的Java代码,可以使用JavaCompiler
接口。但是,它使用起来非常不方便,因为它只是一个真正的Java编译器的接口,它希望编译文件中的整个类定义。
执行运行时提供的代码的最简单方法是使用Rhino JavaScript engine。
这两个选项都只在Java 6中使用,但我相信之前存在脚本界面,所以如果你下载并将它添加到类路径中,你可以在早期的JRE中使用Rhino。
答案 1 :(得分:6)
您需要使用字节码操作库,例如Javassist(Wikipedia),以便运行在运行时提供的任意字符串。 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)