简体   繁体   中英

Confusing Sentence In Generics And Collection Java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM