2008-10-31 20 views
4

這個問題的後續行動: Why can’t I call a method outside of an anonymous class of the same name應該由javac在同名的匿名類之外尋找方法嗎?

這前一個問題的答案爲什麼,但現在我想知道,如果javac的找到運行(INT吧)? (見前面的問題,看看爲什麼運行(42)失敗)

如果它不應該,是由於規範?它會產生不明確的代碼嗎?我的觀點是,我認爲這是一個錯誤。雖然前面的問題解釋了爲什麼這段代碼無法編譯,但我覺得它應該編譯,如果javac在樹中搜索得較高,如果它無法在當前級別找到匹配。 IE瀏覽器。如果this.run()不匹配,它應該自動檢查NotApplicable.this是否有運行方法。

另請注意,正確找到foo(int bar)。如果你給出了找不到run(int bar)的原因,它也必須解釋爲什麼找到foo(int bar)。

public class NotApplicable { 

    public NotApplicable() { 
     new Runnable() { 
      public void run() { 

       // this works just fine, it automatically used NotApplicable.this when it couldn't find this.foo 
       foo(42); 

       // this fails to compile, javac find this.run(), and it does not match 
       run(42); 

       // to force javac to find run(int bar) you must use the following 
       //NotApplicable.this.run(42); 
      } 
     }; 
    } 

    private void run(int bar) { 
    } 

    public void foo(int bar) { 
    } 
} 

回答

4

此行爲符合規範。見§15.12 Method Invocation Expressions在Java語言規範,特別是「編譯時間步驟1」說明了非限定方法調用的含義下段:如果標識符出現可見方法聲明的範圍(§6.3)與內

該名稱,那麼必須有一個封閉類型聲明,該方法是其成員。設T是最內層的類型聲明。的類或接口,以搜尋是T.

換句話說,不合格的方法名稱在所有封閉範圍搜索,和最內「類型聲明」(這意味着一個類或接口聲明)中找到的名稱是將要搜索整個簽名的那個(在「編譯時間步驟2」中)。

+0

謝謝,我想我理解規範。 現在我可以說這是一個不好的規範,應該改變。編譯時間第1步應包括匿名類的封閉類。 – Pyrolistical 2008-10-31 17:44:19

1

聽起來像是不確定性和脆弱性的處方給我 - 只要一個新的方法是在你的基類(好吧,不是那麼容易的接口...)添加代碼的含義完全改變。

匿名類已經非常醜陋了 - 使這一點顯式不會打擾我。

+0

好吧,那爲什麼javac允許找到foo(int bar)?這是相同的配方。 – Pyrolistical 2008-10-31 17:20:25

+0

的確如此。巴,這是一個醜陋的混亂。給我適當的關閉:) – 2008-10-31 17:34:57

1

嘗試

NotApplicable.this.run(42); 

代替。