<の違いは何ですか?Foo>および<Foo>を拡張します


20

私は、違いについて誤解があるようだ<Foo>とし<? extends Foo>。私の理解から、もしあれば

ArrayList<Foo> foos = new ArrayList<>();

これは、タイプのオブジェクトFooをこの配列リストに追加できることを示します。のサブクラスFooもtype Fooであるため、次のようにエラーなしで追加できます。

ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());

ここでBar extends Foo

さて、私が定義されていたと言うfoos

ArrayList<? extends Foo> foos = new ArrayList<>();

私の現在の理解はこれが表現するということsome unknown type that extends Fooです。これは、サブクラスであるオブジェクトFooをこのリストに追加できることを意味します。差がないことを意味ArrayList<Foo>してArrayList<? extends Foo>

これをテストするために、次のコードを記述しようとしました

ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());

しかし、次のコンパイルエラーでプロンプトが出されました

no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)

no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)

現在の理解に基づいて、のFooリストにa を追加できないのは<? extends Foo>、それがサブクラスではないためです。しかし、なぜBarリストに追加できないのか興味があります。

私の理解の穴はどこにありますか?



1
<? extends Foo>ある特定不明拡張するクラスFoo。このクラスを使用した操作は、のサブクラスに対して有効である場合にのみ有効ですFoo
オーダス

3
ワオ。Javaのジェネリックについて学習すればするほど、ねじれた状態になります。
メイソンウィーラー

回答:


15

自分で発見したように、ArrayList宣言されたas ArrayList<? extends Foo> subFoos = new ArrayList<>();はあまり役に立ちません。

これを<? extends T>検討することの有用性を見るために:

List<Foo> collect( List<? extends Foo> a1, List<? extends Foo> a2 )
{
    List<Foo> collected = new ArrayList<>();
    collected.addAll( a1 );
    collected.addAll( a2 );
    return collected;
}

後で次のように使用できます。

List<Foo> foos = collect( new ArrayList<Foo>(), new ArrayList<Bar>() );

または次のように:

List<Foo> foos = collect( new ArrayList<Bar>(), new ArrayList<Foo>() );

collectメソッドが次のように宣言されていた場合、上記のいずれも機能しなかったことに注意してください。

List<Foo> collect( List<Foo> a1, List<Foo> a2 )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.