出于调试原因,我希望能够运行通过控制台输入的代码。例如:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
String str = br.readLine(); //This can return 'a = 5;','b = "Text";' or 'pckg.example.MyClass.run(5);'
if(str == null)
return;
runCode(str); //How would I do this?
}
答案 0 :(得分:5)
我假设您想要将字符串评估为Java代码,而不是像Javascript那样编写脚本引擎,所以 我在阅读this之后使用提到的编译器API标记随意创建了这个。这可能是非常糟糕的做法,但它(有点)的工作方式就像你想要的那样。我怀疑它在调试中会有多大用处,因为它在新类的上下文中运行代码。样本用法包含在底部。
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
public class main {
public static void runCode(String s) throws Exception{
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager sjfm = jc.getStandardFileManager(null, null, null);
File jf = new File("test.java"); //create file in current working directory
PrintWriter pw = new PrintWriter(jf);
pw.println("public class test {public static void main(){"+s+"}}");
pw.close();
Iterable fO = sjfm.getJavaFileObjects(jf);
if(!jc.getTask(null,sjfm,null,null,null,fO).call()) { //compile the code
throw new Exception("compilation failed");
}
URL[] urls = new URL[]{new File("").toURI().toURL()}; //use current working directory
URLClassLoader ucl = new URLClassLoader(urls);
Object o= ucl.loadClass("test").newInstance();
o.getClass().getMethod("main").invoke(o);
}
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
try {
String str = br.readLine(); //This can return 'a = 5;','b = "Text";' or 'pckg.example.MyClass.run(5);'
if(str == null)
return;
runCode(str); //How would I do this?
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
//command line
> System.out.println("hello");
hello
> System.out.println(3+2+3+4+5+2);
19
> for(int i = 0; i < 10; i++) {System.out.println(i);}
0
1
2
3
4
5
6
7
8
9
使用SimpleJavaFileObject,您实际上可以避免使用文件,如here所示,但语法似乎有点麻烦,所以我只选择了当前工作目录中的文件。
编辑:Convert String to Code提供了类似的方法,但尚未完全充实
答案 1 :(得分:4)
如果代码是在JavaScript中,那么您可以使用JavaScript引擎运行它:
Object res = new ScriptEngineManager().getEngineByName("js").eval(str);
自1.6以来,JavaScript引擎是Java SE的一部分。有关详细信息,请参阅本指南http://download.java.net/jdk8/docs/technotes/guides/scripting/programmer_guide/index.html
答案 2 :(得分:3)
您可以使用位于包javax.script
中的Java脚本API。在那里,您可以包含多种脚本语言,例如bsh。
您可以在Oracle的网页上找到programmer's guide。
Rhino,它是某种JavaScript,已经包含在Oracle JVM中。
答案 3 :(得分:0)
为此,您可能需要查看Java Compiler API。我没有研究过它是如何工作的,但它允许你加载一个java文件,在已经运行的系统中编译和加载该类。也许它可以重新用于接受来自控制台的输入。
答案 4 :(得分:0)
对于通用编译器,您可以使用Janino来编译和运行Java代码。 expression evaluator可能有助于您的示例。
如果你只是想在调试时评估表达式,那么Eclispe有Display view允许你执行表达式。请参阅this question。