我在Java编译器中遇到了一个错误,其中提交编译的文件顺序可能导致代码无法编译。我已经深入了解代码,以隔离可以重现问题的最小代码量,从而得到three source files(每个类都有1个类)。用于maven的javac编译命令错误的解决方法
public interface ActionSpec {
public abstract int run(String param);
}
public enum Actions implements ActionSpec {
SKIP {
public int run(String d) {
return 0;
}
};
}
public class Program {
public static void main(String[] args) {
Actions.SKIP.run("hello");
}
}
该问题可以通过以特定顺序拥有javac参数来重现。总之,要想出人头地,动作类必须始终,它使用它的程序前级编译,否则javac的只是不能以理智的方式来对付它:当它发生时
# this case fails
echo "Trying order: javac Program.java Actions.java ActionSpec.java"
rm *class
javac -verbose Program.java Actions.java ActionSpec.java
# this case fails
#rm *class
#javac Program.java Actions.java ActionSpec.java
# this case fails
#rm *class
#javac ActionSpec.java Program.java Actions.java
# this case succeeds
#rm *class
#javac ActionSpec.java Actions.java Program.java
# this case succeeds
#rm *class
#javac Actions.java ActionSpec.java Program.java
# this case succeeds
#rm *class
#javac Actions.java Program.java ActionSpec.java
编译错误, ,始终是相同的 - 即使它们都实现了具有该运行方法的接口,仍无法找到Actions枚举实例上的运行方法。
Program.java:6: cannot find symbol
symbol : method run(java.lang.String)
location: class problem.Actions
Actions.SKIP.run("hello");
该错误似乎与this one reported on Oracle's site有关。 我在mac os x 10.7.2 x86_64上使用javac 1.6.0_29,但也在Linux上转载了它。
当我使用Maven构建时,此问题变得明显,并且似乎没有任何对编译顺序的控制权。所以我正在寻找一种解决方法,迫使maven按照避免编译器错误的顺序编译文件,或者避免使用编译器标志(或类似的东西)来避免它。这个问题在工作站和持续集成环境中都会出现,所以它必须全面工作。有什么建议么?
编辑:只是尝试了以下解决方法,尽管只是将问题的枚举分配给变量与它实现的接口的类型,出人意料地导致错误消失。
public class Program {
public static void main(String[] args) {
ActionSpec a = Actions.SKIP;
a.run("hello");
}
}
对其他意见仍然感兴趣。
引入ActionSpec开始工作并不奇怪。也许这个bug只限于enum和它的实现。 “进口”也可能有帮助。 – 2012-02-29 21:03:27
你有没有尝试添加一个'公共抽象int运行(字符串d);'枚举的方法? – 2012-02-29 21:25:45
应该不需要,因为枚举类实现了接口,并且它的所有实例都包含该方法的实现(否则枚举不会编译)。 – 2012-02-29 23:06:30