A extends X,
次の宣言が有効な場合
List<? extends X> list = new ArrayList<A>();
リストは、X を拡張する要素のコレクションを保持するように思われます。そのため、new A()
修飾する必要があります。
はい、そうではありません。何故ですか?
あなたはほとんどそれを持っています。 List<? extends X>
「X(またはX自体)のサブタイプであるタイプ(実際にはわかりません)のリスト」を意味します。
問題は、Xがたとえばの場合Number
です。次に、またはまたは他のタイプをList<? extends X>
意味します。これは、実際にはわからないと言ったばかりです。に何も挿入できません。したがって、リストの要素のタイプがわからないため、に何も挿入できません。ただし、リストから値を取得することはでき、リストに含まれる値は少なくとも。であることが保証されます。List<Double>
List<Integer>
Number
List<Integer>
List<? extends Number>
Number
詳細については、項目28:制限付きワイルドカードを使用してEffective Java、第2版でAPIの柔軟性を高めるを参照してください。Joshua Bloch(すべてのJavaプログラマーが本棚に置くべき本)。特に、この項目では、「プロデューサー拡張、コンシューマースーパー」を意味するニーモニックPECSについて説明します。これは、Javaジェネリックでのandキーワードの意味と、それらをいつ使用する必要があるかを思い出すのに役立ちます。extends
super
List<? extends X>
明確な型ではありません。これは、変数が, だけでなく(where )list
などのさまざまな型から割り当てられることを意味します。コンパイラがそのようなリストへの追加を許可した場合、 toを追加することになります。それはタイプセーフの失敗です。List<A>
List<B>
B extends X
new A()
A
List<B>
extends
ジェネリック型のリスト参照 (変数) を作成しています。これは、リストがスーパークラスとして持つクラスのインスタンスを保持できることを示しますX
。ただし、リストの実際のインスタンスを作成するときは、 class のインスタンスのみを保持するように制限しますA
。奇妙に聞こえませんか?