我目前正在制作一个工具,根据用户输入输出要使用的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");
}
}
答案 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
,则编译器将在int
和i2d
之间发出getfield
条指令,以将dstore
转换为{ {1}}。如果int
的类型为double
,则编译器将发出对f
的调用,以在存储之前将已加载的值取消装箱。如果Double
的类型为doubleValue()
,则在没有强制转换的情况下,该分配在Java中是非法的(如果它是合法的,则为f
指令)。如果Object
的班级没有名为checkcast
的字段,则此作业无法翻译。
当调用具有未知签名的方法时,类似的注意事项适用,这可能需要为其每个参数进行转换和/或为varargs调用创建数组。此外,在JVM级别,允许对返回类型进行重载,因此即使只有一个参数类型列表,也必须指定返回类型。
你可以做的最好的事情是提供未知类的虚拟声明,以便编译器知道该怎么做,正如paulsm4的回答所示。