2013-07-12 96 views
8

下面的代碼片段(從真實代碼中抽象出來)編譯並在Eclipse中運行。Eclipse和javac之間奇怪的編譯器區別

包1/Outer.java:

package package1; 

import package1.Outer.Mid.Inner; 
import package2.Bar; 

public class Outer { 
    final Mid mid = new Mid(); 

    public Outer() { 
     mid.setInner(new Inner() { 
      @Override public void foo() { 
       System.out.println("In Outer.foo()"); 
      } 
     }); 
    } 

    public static class Mid implements Bar { 
     private Inner inner; 

     public void setInner(Inner inner) { 
      this.inner = inner; 
     } 

     public Inner getInner() { 
      return this.inner; 
     } 

     @Override 
     public void bar() {} 

     interface Inner { 
      void foo(); 
     } 
    } 

} 

包2/Bar.java:

package1\Outer.java:31: cannot find symbol 
symbol : class Bar 
location: class package1.Outer 
     public static class Mid implements Bar { 
             ^
package1\Outer.java:42: method does not override or implement a method from a supertype 
       @Override 
       ^
2 errors 

現在:

package package2; 

public interface Bar { 
    void bar(); 
} 

然而,使用javac編譯時失敗,此錯誤,如果我切換導入語句的順序,如下所示:

import package2.Bar; 
import package1.Outer.Mid.Inner; 

...然後它在Eclipse和javac中編譯。顯然,進口報表的順序似乎很重要......但爲什麼?

注:

  • 我測試了使用Java JDK 1.6.0_30和Java的也JDK 1.7.0_21。如果這是一個已經修復的錯誤,那麼很好理解。
  • 我覺得奇怪,我說package1.Outer.Mid.Inner導入甚至是必要的,考慮到Inner接口嵌套在Outer.java,但是Eclipse和javac似乎都需要它
  • 我發現了這個問題試圖運行的Ant構建生產代碼具有相似的結構。在Eclipse中一切都很好,但Ant腳本拒絕通過。
+0

我不確定,但是Eclipse很可能會給出一個不同於你手工編譯的命令。也許順序是倒置的。唯一的另一種可能性是java編譯器的不同版本。 – Gene

+3

任何機會,你可以刪除你的代碼中多餘的部分,並留下我們仍然產生相同的奇怪結果的最小值? – arshajii

+0

@Gene Eclipse有它自己的編譯器。 – EJP

回答

4

這看起來像一個bug,正如Oracle的bug數據庫here所報告的那樣。

根據JLS §7.5,訂單import-陳述應該沒有關係。

+0

鏈接的bug在版本1.6u1中標記爲已修復。 – EJP

+0

@EJP查看更新 – arshajii

+0

@arshaji更新後的鏈接看起來符合我的情況,很好找。對於JLS,我沒有明確提到進口聲明順序無關緊要......這是一種隱含的理解還是我只是盲目的? –

相關問題