0

我有一个带有编辑器的 JavaFX 应用程序。在编辑器中,用户将能够编写 java 代码,我有一个按钮来编译这段代码并运行 main 方法。例如,编辑器将包含以下代码:

public class Test {
    public static void main(String[] args) {
        System.out.println("hello");
    }
}

单击按钮将运行以下代码:

runButton.setOnAction(e -> {
        compiler.set(editor.getText());
        try {
            compiler.createFile();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        compiler.compile();
        compiler.run();

    });

在编译器类中,有如下实现:

public class CodeCompiler {

public String className;
public String code;

public void set(String code) {
    try {
        this.className = code.substring(code.indexOf(" class ") + 6, code.indexOf(" {")).trim();
    } catch(StringIndexOutOfBoundsException e) {

    }
    this.code = code;
}

public void createFile() throws IOException {
    PrintWriter pw = new PrintWriter("speech2code/src/main/java/" + className + ".java");
    pw.close();
    FileWriter writer = new FileWriter("speech2code/src/main/java/" + className + ".java", true);
    writer.write(code);
    writer.flush();
    writer.close();
}

public void compile() {
    File file = new File("speech2code/src/main/java/" + className + ".java");
    File classFile = new File("speech2code/src/main/java/" + className + ".class");
    classFile.delete(); // delete class file f it exists
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    compiler.run(null, null, null, file.getPath());
}

public void run() {

    Class<?> cls = null;
    try {
        cls = Class.forName(className);
        System.out.println(cls == null);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    Method meth = null;
    try {
        meth = cls.getMethod("main", String[].class);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    String[] params = null;
    try {
        meth.invoke(null, (Object) params);
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }

}


}

现在上面的代码成功地创建了java文件,class文件并且第一次正确运行。现在,当我更改编辑器代码以打印其他内容时,它会输出代码第一次运行的结果。所以,在这种情况下,它仍然会打印 'hello' 而不是它的当前值。

有什么问题可能是错的吗?谢谢!

4

1 回答 1

0

您需要为新类创建一个新的类加载器。该类不会因为您编译它而重新加载。

 URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] {classFile});

然后你可以向这个加载器询问这个类:

Class<?> cls = Class.forName(className, true, classLoader);
于 2017-02-06T07:20:38.207 回答