java 动态代码执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4166135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic code execution
提问by Sid
Similar to dynamic SQL, wherein a String is executed as an SQL at runtime, can we have Java code run dynamically? Like I return a String which is a Java code and then I execute at runtime. Is this possible?
类似于动态 SQL,其中 String 在运行时作为 SQL 执行,我们可以动态运行 Java 代码吗?就像我返回一个字符串,它是一个 Java 代码,然后在运行时执行。这可能吗?
回答by Michael Borgwardt
For real Java code, this is possible using the JavaCompiler
interface. However, it's very inconvenient to use since it's just an interface to a real Java compiler that expects to compile entire class definitions found in files.
对于真正的 Java 代码,这可以使用JavaCompiler
接口实现。然而,它使用起来非常不方便,因为它只是一个真正的 Java 编译器的接口,它期望编译文件中的整个类定义。
The easiest way to execute code supplied at runtime would be to use the Rhino JavaScript engine.
执行运行时提供的代码的最简单方法是使用Rhino JavaScript 引擎。
Both of these options have been only in Java 6, though I believe the scripting interface existed before, so you could use Rhino in an earlier JRE if you download and add it to the classpath.
这两个选项都只在 Java 6 中出现过,尽管我相信脚本接口以前就存在,所以如果你下载并将其添加到类路径中,你可以在早期的 JRE 中使用 Rhino。
回答by Andrzej Doyle
Javassist
Javassist
You would need to use a bytecode manipulation library such as Javassist(Wikipedia), in order to run an arbitrary string that is provided at runtime. Javassist allows you to create a CtClass
based on a string representing source code; and can then turn this into compiled Class
object via a particular classloader, so that the class is then available to your application. Other libraries would need to do something similar to these two steps in order to achieve the same thing.
您需要使用字节码操作库,例如Javassist( Wikipedia),以便运行在运行时提供的任意字符串。Javassist 允许您创建一个CtClass
基于表示源代码的字符串;然后可以Class
通过特定的类加载器将其转换为编译对象,以便您的应用程序可以使用该类。其他库需要执行与这两个步骤类似的操作才能实现相同的目标。
So it is possible, but it's very heavyweight and is likely to make your application very hard to reason about. If at all possible, consider designing a very flexible class statically, and having it accept parameters that control its behaviour.
所以这是可能的,但它非常重量级,可能会使您的应用程序非常难以推理。如果可能,请考虑静态设计一个非常灵活的类,并让它接受控制其行为的参数。
回答by jbindel
If you want to do more than invoke an existing method dynamically, you may need to compile your String into bytecode. An easy way to do this is to include the Eclipse/JDT compiler jar in your classpath, and then you can use that to compile your String into a Class, which can then be loaded.
如果您想做的不仅仅是动态调用现有方法,您可能需要将您的字符串编译成字节码。一种简单的方法是将 Eclipse/JDT 编译器 jar 包含在您的类路径中,然后您可以使用它将您的 String 编译为一个类,然后可以加载该类。
This type of dynamic code generation and execution is used to convert JSP files into Servlets and is used in other packages such as JasperReports to turn a report specification into a Class that is then invoked.
这种类型的动态代码生成和执行用于将 JSP 文件转换为 Servlet,并在其他包中使用,例如 JasperReports,将报表规范转换为随后调用的类。
Remember that just as with SQL you must be careful to prevent code injection security problems if any of the String contains user-specified data.
请记住,就像使用 SQL 一样,如果任何字符串包含用户指定的数据,您必须小心防止代码注入安全问题。
回答by Yuriy
You also may want to look at Java 6 scripting support: http://download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm
您可能还想查看 Java 6 脚本支持:http: //download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm
Here is a version of hello world that creates array of strings and prints a first one:
这是一个创建字符串数组并打印第一个字符串的 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])");
}
}
回答by Travis Webb
Yes it is possible. Look at the Java Compiler API. Have a look here:
对的,这是可能的。查看 Java 编译器 API。看看这里:
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html