我在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