的上限通配符是必要的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
可以是Dog
,Cat
,AnyOtherConcreteAnimal
。通過將其更改爲上限通配符
void addAll(Collection<? extends T> t){};
你說你期待一個收集與具體類型的Animals
,而不是隻T
這是Container<Animals>
。現在,這將再次工作
animalContainer.addAll(cats); // will work since addAll(Collection<? extends T> t)
任何擴展E也是E.但是,因爲泛型是不變的,同樣的原則不適用。 – bcsb1001
@ bcsb1001其中不變性意味着「收集」不是「收集」。請參閱https://stackoverflow.com/q/2745265/3788176。 (提供給OP的好處,不是你的;它只是從你的評論:)) –