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

在Collection.addAll的參數是Collection<? extends E>一些問題,我認爲,這意味着電子商務的所有子類可以使用,但在Collection.add的參數是E.我認爲這意味着只有E類可以使用。在Collection.add和Collection.addAll

那麼爲什麼E的子類不能在這個方法中參數?如<T extends E> boolean add(T t);

+5

任何擴展E也是E.但是,因爲泛型是不變的,同樣的原則不適用。 – bcsb1001

+4

@ bcsb1001其​​中不變性意味着「收集」不是「收集」。請參閱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)是容器將只接受類型T這是Animal,但由於貓列表是Cat類型它違反了利弊traints。

由於Animal可以是DogCat,AnyOtherConcreteAnimal。通過將其更改爲上限通配符

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

你說你期待一個收集與具體類型的Animals,而不是隻T這是Container<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

對不起,我不認爲這些答案可以解決我的問題。 –

相關問題