java - 从 Java 中的字符串运行代码

标签 java

<分区>

出于调试原因,我希望能够运行通过控制台输入的代码。例如:

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?
}

最佳答案

请不要实际使用它

我假设您想将字符串计算为 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提供了类似的方法,但还没有完全充实

关于java - 从 Java 中的字符串运行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17608392/

相关文章:

java - 为什么我的输入 -100000000000000 得到不正确的输出?

java - 在 IntelliJ JUnit 运行配置中共享环境变量

java - 了解 Groovy 中的 findAll

java - 获取在后台运行的 Java 运行时进程

java - 陷入了从自身内部循环 if 语句的困境

java - 在tomcat中更改属性文件时出错

java - java字符串中equals和compareto方法的区别

java - 使用这样的 Jbutton 设置单击 "Next"按钮后,我将如何执行操作?

java - 使用 Java EE 保留我的第一个实体

java - spock 测试中的模拟 java 类没有被执行