2016-01-10 168 views
8

Java的8允許定義內部接口的靜態方法,但restricts它調用的唯一接口名稱:非法靜態接口方法調用

9.4: An interface can declare static methods, which are invoked without reference to a particular object.

如:

interface X { 
    static void y() { 
    } 
} 

... 

X x = new X() {}; 
x.y(); 

原因錯誤:

error: illegal static interface method call 
     x.y(); 
      ^
    the receiver expression should be replaced with the type qualifier 'X' 

通常在JLS這樣的禁令有一個解釋。在這種情況下,我沒有發現任何細節。所以我在尋找這個規則的全面或權威的解釋:爲什麼禁止通過特定的對象引用來調用靜態方法?它破壞了什麼?

+14

也許更好的問題是爲什麼可以首先在對象引用上調用靜態方法...... –

+1

在那個筆記上,我們如何獲得上面一行中的接口X的實例? – aiguy

+2

完全同意@SkinnyJ我認爲Java開發人員正試圖通過創建一個實現該接口的匿名類來改正他們通過使對象具有靜態可用性而造成的錯誤,這些對象有點令人困惑 – silentprogrammer

回答

16

這是一個相當強烈的共識,即所謂的語法問題不應該被允許用於類的靜態方法,但是到了意識到的時候改變已經太遲了。最近添加的接口方法還爲時不晚。

此外,允許此語法會引入菱形問題的可能性,因爲類可以實現定義碰撞方法的接口。

+8

這種分析是正確的。我們認爲通過實例調用靜態方法成爲語言設計錯誤的能力是不幸的,不幸的是我們無法追溯到類的修復。我們至少可以不犯同樣的錯誤。 (有時候我們會選擇在擴展語言時故意「犯同樣的錯誤」,選擇與本地改進相一致的選項 - 但是選擇需要判斷「好,改善多少好」?這裏差別很大足夠。) –

+1

@Brian Goetz:...如果新的'static'接口方法比以前調用的實例方法更具體,它可能會破壞現有代碼(一旦重新編譯)。我想,這也是(非)繼承靜態接口方法的原因之一。接口的發展對現有的實現可能影響最小。 – Holger

+1

@Holger ...而且,同時引入默認和可繼承的靜態會導致更多的混淆。很多理由在這裏畫這條線。 –