2017-08-09 43 views
3

我的理解下面的代碼應該運行沒有任何編譯錯誤。編譯失敗,通用類與通用接口

但是,當我運行這個程序時,我收到以下編譯錯誤。

The member type B.D cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type B

class B<X> { 
    interface C { 
    } 

    interface D<Y> { 
    } 
} 

class Test { 
    // compilation fails here 
    B<String>.D<String>[] arr = new B<String>.D<String>[10]; 
} 

請幫助我理解這種行爲。

+0

爲了記錄:我從您的示例中刪除了第一個A類 - 因爲該類不會導致整體問題。所以我覺得它很混亂。 – GhostCat

+0

@ GhostCat-謝謝。 –

回答

4

以類似於內部static類的方式,嵌套接口不與其外部類的實例關聯,而僅與類本身有關聯。無論B的類型參數如何,所有static成員在B的所有實例中共享。試想一下:

class B<T> { 
    public static int shared = 0; 
} 

變量sharedB<String>B<Integer>B<Object>等相同。訪問它的一個參數B的嘗試導致編譯錯誤:

int copy = B<String>.shared; // <<== Does not compile 

因此,中B類型參數對的arr的聲明沒有任何影響,所以Java希望你刪除它:

B.D<String>[] arr = new B.D[10]; 
+0

@GhostCat我沒有研究*你的編輯,我記得大部分*我的編輯都是這樣的。此外,格式化,我經常爲了能夠自己閱讀問題而做的;-) – dasblinkenlight

+0

除此之外:看到你7到10周......傳說中的下一個;-) – GhostCat

1

內部接口始終是static(與類不同)。因此B的參數String在定義new B<String>.D<String>中沒有意義。

2

首先,你可以用而不是創建具體參數化類型的數組。例如:

Pair<Integer,Integer>[] intPairArr = new Pair<Integer,Integer>[10]; // illegal 

不起作用。詳情請參閱here

但它看起來像編譯器在這裏給你,因爲它第一絆倒在事實嵌套接口類似於靜態內部類不同,少有用的錯誤消息。

所以,你唯一可以做的事情是:忽略的賦值的RHS泛型類型:

B.D<String>[] arr = new B.D[10]; 

這當然會導致類型安全警告 - 並使得整體構思該內部接口通用性已經過時了。

所以真正的答案可能是:泛型和數組在Java中不能很好地結合在一起 - 首先避免使用它們。通過引入界面嵌套結果的「更好的用戶體驗」,使得事物更加複雜不要感到驚訝。