次のような単純なクラス構造を持ちます。
class A {
}
class B extends A {
}
class C extends B {
}
以前作成したクラスのオブジェクトを保持するために ArrayList を作成しています。
List<? extends A> list1 = new ArrayList<A>();
List<? extends B> list2 = new ArrayList<B>();
List<? extends C> list3 = new ArrayList<C>();
List<? super A> list4 = new ArrayList<A>();
List<? super B> list5 = new ArrayList<B>();
List<? super C> list6 = new ArrayList<C>();
これらの各リストに、以前に作成したクラス A、B、C のオブジェクトをそれぞれ 1 つずつ追加しようとしています。可能な組み合わせは次の 3 つだけです。
クラス A、B、C のオブジェクトをリスト 4 に追加する
クラスBとCのオブジェクトをリスト5に追加する
クラス C のオブジェクトをリスト list6 に追加します。残りの試行では、次のようなコンパイラ エラーが発生します。
リスト型のメソッドadd(capture#1-of ? extends A)は引数(A)には適用できません。
クラス A、B、C のオブジェクトを list1/2/3 に追加できないのはなぜですか? たとえば、list4 が定義されているように、クラス A のスーパークラスであるはずなのに、なぜ list4 はクラス A、B、C のオブジェクトを受け入れるのですか?
ベストアンサー1
「? extends A」は「A(またはA自体)から派生した型」を意味します。つまり、例えば、aList<ByteArrayOutputStream>
はと互換性がありますList<? extends OutputStream>
が、そのようなリストにaを追加することはできませんFileOutputStream
。aはaであることを意味しますList<ByteArrayOutputStream>
。わかっているのは、フェッチするものはすべてからリストはOutputStream
何らかのものになります。
「? super A」は「A(またはA自体)のスーパークラスである何らかの型」を意味します。したがって、たとえば、aはList<OutputStream>
と互換性がありますList<? super ByteArrayOutputStream>
。このようなリストにaを追加することは間違いなく可能ですByteArrayOutputStream
が、リストから項目を取得する場合、それについてはあまり保証できません。
見るアンジェリカ・ランガーのジェネリック医薬品に関するよくある質問さらに詳しい情報については。