2012-03-19 25 views
11

ダイヤモンド演算子を使用して2番目のマップ宣言が最初のものがコンパイルされないのはなぜかと思います。コンパイルエラー:ダイヤモンド演算子を使用した二重ブレースの初期化(匿名の内部クラス)

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"); 
     } 
    }; 

EDIT
おかげで - 私はより良いコンパイルエラーを読んでいる必要があります。 私はあなたがここに静的初期化子(静的が完全に不足しているキーワードを)持っていない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 *初期化子がありますか? –

+0

@JonSkeetあなたは正しいです、 "二重ブレース"と呼ばれる方法を覚えていません... – assylias

+0

エラーは 'EnumMap'を参照していますが、あなたのコードには' HashMap'しかありません。 –

答えて

6

でexaplanationを発見しました。

基本的には、新しい匿名サブクラスHashMapを作成し、ここにインスタンスの初期化ブロックを定義します。 Btw、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

+1

正しい...「Java genericsを無視しています」 –

3

この機能は、それがコールAllowing the diamond syntax with some anonymous class constructorsプロジェクトコイン2の一部で、2016年

の9月22日に来たJava 9につきになります。

Link.

+0

https://bugs.openjdk.java.net/browse/JDK-8062373も参照してください。 –

関連する問題