2012-03-19 105 views
11

我想知道爲什麼第二個地圖聲明(使用鑽石算子)不能編譯時,第一個。編譯錯誤:與鑽石操作員的雙括號初始化(匿名內部類)

error: cannot infer type arguments for HashMap; Map map2 = new HashMap<>() { reason: cannot use '<>' with anonymous inner classes where K,V are type-variables: K extends Object declared in class HashMap V extends Object declared in class HashMap

代碼:

Map<String, String> map1 = new HashMap<String, String>() { //compiles fine 

     { 
      put("abc", "abc"); 
     } 
    }; 

    Map<String, String> map2 = new HashMap<>() { //does not compile 

     { 
      put("abc", "abc"); 
     } 
    }; 

編輯
謝謝您的回答 - 我應該更好地閱讀編譯錯誤。 我發現exaplanation在JLS

It is a compile-time error if a class instance creation expression declares an anonymous class using the "<>" form for the class's type arguments.

+4

您的標題中引用的* static *初始值設定項在哪裏? – 2012-03-19 16:15:52

+0

@JonSkeet你是對的,不記得「雙大括號」是怎麼被調用的...... – assylias 2012-03-19 16:16:45

+0

這個錯誤引用了一個'EnumMap',但是你的代碼中只有'HashMap's。 – 2012-03-19 16:16:55

回答

6

你沒有靜態初始化這裏(關鍵字靜態全部丟失)。

基本上你創建了一個新的匿名子類HashMap並在這裏定義了實例初始化塊。順便說一句,這隻適用於HashMap是不是最終。

因爲你會得到HashMap一個匿名子類金剛石操作不在這裏工作,因爲子類將被編譯爲,如果你寫了... extends HashMap<Object, Object>,這顯然是不兼容Map<String, String>

4

鑽石推理不適用於實例化匿名類,這就是你在這裏做的。

試試這個:

Map<String, String> map1 = new HashMap<>(); 

{ 
    map1.put("abc", "abc"); 
} 
1

請注意,您可以完全省略了鑽石。然而,在編譯時,只是因爲它忽略了Java泛型,並且依賴於Java與以前版本向後兼容的事實。

Map<String, String> map1 = new HashMap() { //compiles fine 
    { 
     put("abc", "abc"); 
    } 
}; 
+0

是的,這是有效的,但有警告... – assylias 2014-06-12 17:48:47

+1

正確...因爲它忽略了Java泛型 – 2014-06-12 18:16:05

3

此功能項目的一部分,硬幣2,將在Java的9 avalaible未來9月22日的2016年

這是呼叫Allowing the diamond syntax with some anonymous class constructors

Link.

+0

另請參閱https://bugs.openjdk.java.net/browse/JDK-8062373 – 2017-09-01 14:26:34