なぜ
List<Map<String, Object>> a, b;
a.addAll(b);
コンパイル
しかし
List<? extends Map<String, ?>> a, b;
a.addAll(b);
ではない。
後者をコンパイルするにはどうすればよいですか?
なぜ
List<Map<String, Object>> a, b;
a.addAll(b);
コンパイル
しかし
List<? extends Map<String, ?>> a, b;
a.addAll(b);
ではない。
後者をコンパイルするにはどうすればよいですか?
CustomHashMap
それが拡張され、次のようHashMap
に初期化すると想像してください。a
List<CustomHashMap<String, String> list = new ArrayList<CustomHashMap<String, String>>();
List<? extends Map<String, ?>> a = list;
エントリを追加できた場合a
...
a.add(new HashMap<String, String>());
...この奇妙な状況に遭遇するでしょう
CustomHashMap<String, String> map = list.get(0); // you would expect to get CustomHashMap object but you will get a HashMap object instead
言い換えれば、Map の実際の型がわからず (? extends Map と言うとき)、わかっていることは、それが Map の何らかのサブタイプであり、List に任意のオブジェクトを追加することができないということだけです。追加されたオブジェクトのスーパータイプがあることを確認してください。ただし、マップの正確なタイプが不明であるため、できません。
ワイルドカード ジェネリック リストにアイテムを追加することはできません。最初のものは、定義された型を持っているためコンパイルされます。
ただし、目的に合ったスーパー クラスを見つけて、それをジェネリック引数として使用することもできます。
アップデート:
ワイルドカードも参照してください (Oracle ドキュメント内)
具体的な Generic Type で宣言すると、コンパイルされます。クラスを定義する場合:
public class AClass<T extends Map<String, ?>> {
public List<T> dostuff() {
List<T> lista = new ArrayList<T>();
List<T> listb = new ArrayList<T>();
lista.addAll(listb);
return lista;
}
}
ワイルドカードを使用すると、コンパイルできません。
次のような方法を使用して実行できます。
private <S extends Map<String, ?>> void method(List<S> a, List<S> b){
a.addAll(b);
}