2017-08-09 8 views
2
boolean addAll(Collection<? extends E> c); 
boolean add(E e); 

Collection.addAllでparamはCollection<? extends E>あるでいくつかの質問は、私はそれがEのすべてのサブクラスが使用できることを意味だと思いますが、Collection.addでparamが、私はそれを考えるE.ですEクラスのみを使用できることを意味します。Collection.addとCollection.addAll

なぜ、このメソッドでEのサブクラスをparamできないのですか?このような<T extends E> boolean add(T t);

+5

Eを拡張するものもすべてEです。しかし、ジェネリックは不変であるため、同じ原則は当てはまりません。 – bcsb1001

+4

@ bcsb1001ここで、不変性とは、「Collection 」が「Collection 」ではないことを意味します。 https://stackoverflow.com/q/2745265/3788176を参照してください。 (あなたの利益ではなくOPの利益のために提供されています;あなたのコメントからちょうど後に続きます:) –

答えて

1

上限ワイルドカードは型Tのコレクションのは、次のような構造

class Animals{} 
class Dog extends Animals{} 
class Cat extends Animals{} 

class Container<T>{ 
    void add(T t){}; 
    void addAll(Collection<T> t){}; 
} 

を見てみましょうするために必要であり、我々はそれをインスタンス化し、この

ArrayList<Dog> dogs = new ArrayList<>(); 
dogs.add(new Dog()); 

ArrayList<Cat> cats = new ArrayList<>(); 
cats.add(new Cat()); 

Container<Animals> animalContainer = new Container<>(); 
animalContainer.add(dogs.get(0)); // will work since add(T t) 
animalContainer.addAll(cats); // will not work since addAll(Collection<T> t) 

理由のようにそれを使用するようにaddAll(Collection<T> t)とはうまくいかない理由は、コンテナがタイプTAnimal)のみを受け入れることですが、catリストのタイプがCatなので、それはコンプライアンス違反ですtraints。 Animalので

DogCatAnyOtherConcreteAnimalであることができます。上限ワイルドカード

void addAll(Collection<? extends T> t){}; 

にそれを変更することであなたはAnimalsの具体的なタイプのコレクションを期待していないだけTContainer<Animals>であることを言います。そして、これは再び働くでしょう

animalContainer.addAll(cats); // will work since addAll(Collection<? extends T> t) 
+0

なぜ動物は 'animalContainer.add(dogs.get(0));'で犬になることができますか? –

+0

@ sibo.wangこちらをご覧くださいhttps://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p –

+0

申し訳ありませんが、私は考えませんそれらの答えは私の質問に対処することができます。 –

関連する問題