0

我目前正在制作一个工具,它将根据用户输入输出 Java 类文件以供使用。我输出了一组 .java 文件,其中一些引用了当前上下文中不存在的类和变量。因此,当我编译时,输出文件会记录这些错误并且不会编译该类。我的问题是:有没有办法使用 JavaCompiler 按原样编译类文件?

这是编译代码:

public static void compileAll(File file) throws IOException{
    String fileToCompile = "C:/test.java";
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    FileOutputStream errorStream = new FileOutputStream("Errors.txt");
    int compilationResult = compiler.run(null, null, errorStream, "-verbose", fileToCompile );
    if(compilationResult == 0){
        System.out.println("Compilation is successful");
    }else{
        System.out.println("Compilation Failed");
    }
}
4

2 回答 2

0

你想要的是不可能的,因为 Java 编译器需要在字节码生成时知道类型以及变量和方法的名称。因为 Java 字节码是类型化的,并且 JVM 不知道一些 Java 源代码级别的转换(例如,拆箱转换纯粹是 Java 编译器约定),所以编译器无法摆脱发出“加载字段f”或“调用方法”的字节码foo"; 编译器必须说“加载f类型的字段double”或“调用f类型的方法int(double, Object)”。

考虑读取对象的未知字段并将其分配给double局部变量:

double d = o.f;

如果类型fdouble,编译器将简单地使用 agetfield后跟 adstore进入局部变量 slot for d。如果f是 类型,编译器将在和之间int发出一条i2d指令将 转换为。如果是 type ,编译器将在存储加载值之前发出调用以将加载的值拆箱。如果是 type ,则赋值在没有强制转换的 Java 中是非法的(如果它是合法的,这将是一条指令)。如果 的 类没有名为 的字段,则该作业没有可能的翻译。getfielddstoreintdoublefDoubledoubleValue()fObjectcheckcastxx

调用具有未知签名的方法时也需要考虑类似的考虑,这可能需要对其每个参数进行转换和/或为可变参数调用创建数组。此外,在 JVM 级别,允许对返回类型进行重载,因此即使只有一个参数类型列表,也必须指定返回类型。

您能做的最好的事情是提供未知类的虚拟声明,以便编译器知道该怎么做,正如 paulsm4 的回答所建议的那样。

于 2014-06-21T01:24:41.600 回答
0

问:有没有办法使用 JavaCompiler 来编译类文件?

是的:根据需要创建虚拟方法和/或虚拟类,以便您可以编译:)

于 2012-06-06T23:04:59.023 回答