I am reading a book: Java Generics and Collections by maurice and philip.
There is one sentence which i think is wrong: They have given a code:
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
and the sentence is:
The quizzical phrase ? super T means that the destination list may have elements of any type that is a supertype of T, just as the source list may have elements of any type that is a subtype of T.
AFAIK, the ? super T
? super T
means destination list can have elements which are T and its SubType. I have tested this here:
List<? super Dog> tList = new ArrayList<>();
tList.add(new Dog());
tList.add(new HotDog());
where tList.add(new Animal());
is not allowed. note that HotDog extends Dog
and Dog extends Animal
So if we go according to the book statement, which says tList(Destination list), being ? Super Dog(? super T)
? Super Dog(? super T)
, can have Animal's instance as it is the Super Type of Dog(T)
The statement about List<? super T>
List<? super T>
that it "may have elements of any type that is a supertype of T" is supposed to mean that you first have to choose a definite type U
that is a supertype of T
, and then it claims that the list will contain elements of type U
. This is a very obscure way of explaining it, so let my try to frame it better.
The notation List<? super Dog>
List<? super Dog>
does not describe one particular list type; it is better understood as a pattern against which specific list types are matched. List<Dog>
and List<Animal>
match this pattern, but List<HotDog>
does not.
Now, if you review the above, you'll see that you can safely add objects of type Dog
to any list that satisfies the given pattern; in fact, the pattern exactly covers all list types where this is safe. Further note that "objects of type Dog
" automatically includes all subtypes of Dog
because that's the essence of the concept "subtype".
This is why we use the <? super T>
<? super T>
wildcard to generally describe a list that will accept objects of type T
(it will play the role of a consumer of T
).
The opposite case, that of <? extends Dog>
<? extends Dog>
, describes all list types that can serve as producers of objects of type Dog
.
All of the above rules are succintly summarized in the PECS principle: "Producer extends
, consumer super
."
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.