JavaCompiler API强制编译错误?

时间:2012-06-06 23:00:50

标签: java class compiler-construction compilation

我目前正在制作一个工具,根据用户输入输出要使用的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");
    }
}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

您想要的是不可能的,因为Java编译器需要在字节码生成时知道类型以及变量和方法的名称。因为Java字节码是类型化的,并且JVM不知道某些Java源代码级别的转换(例如,拆箱转换纯粹是Java编译器惯例),编译器无法使用发出字段代码来说明“加载字段f “或”调用方法foo“;编译器必须说“f类型的加载字段double”或“{1}}类型的调用方法f”。

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

double

如果double d = o.f; 的类型为f,则编译器只需使用double后跟getfield进入dstore的局部变量槽。如果d的类型为f,则编译器将在inti2d之间发出getfield条指令,以将dstore转换为{ {1}}。如果int的类型为double,则编译器将发出对f的调用,以在存储之前将已加载的值取消装箱。如果Double的类型为doubleValue(),则在没有强制转换的情况下,该分配在Java中是非法的(如果它是合法的,则为f指令)。如果Object的班级没有名为checkcast的字段,则此作业无法翻译。

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

你可以做的最好的事情是提供未知类的虚拟声明,以便编译器知道该怎么做,正如paulsm4的回答所示。