JavaCompiler API 强制编译时出现错误?

问题描述 投票:0回答:2
我目前正在制作一个工具,它将根据用户输入输出 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"); } }
    
java class compilation java-compiler-api
2个回答
0
投票
问:有没有办法使用JavaCompiler原样编译class文件?

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


0
投票
你想要的是不可能的,因为Java编译器需要在字节码生成时知道变量和方法的类型以及名称。 由于 Java 字节码是类型化的,并且 JVM 不知道某些 Java 源代码级转换(例如,拆箱转换纯粹是 Java 编译器约定),因此编译器无法摆脱发出“load field

f

”或“调用方法
foo
”;编译器必须说“加载类型为
f
的字段
double
”或“调用类型为
f
的方法
int(double, Object)
”。

考虑读取对象的未知字段并将其分配给

double

局部变量:

double d = o.f;

如果

f

 的类型是 
double
,编译器将简单地使用 
getfield
 后跟 
dstore
d
 的局部变量槽中。  如果 
f
 的类型为 
int
,编译器将在 
i2d
getfield
 之间发出 
dstore
 指令,将 
int
 转换为 
double
。  如果 
f
 的类型为 
Double
,编译器将发出对 
doubleValue()
 的调用,以在存储加载的值之前将其拆箱。  如果 
f
Object
 类型,则在没有强制转换的情况下,在 Java 中赋值是非法的(如果合法的话,这将是 
checkcast
 指令)。  如果 
x
 的类没有名为 
x
 的字段,则此作业无法翻译。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.