Java, generics and PECS: still having trouble unde

2019-09-03 07:04发布

问题:

I'll post a single link here: Collections.sort(). There have been many posts on SO with regards to the PECS paradigm, including this one. In my own personal code, I use generics quite a lot, but have only ever had the use of the P part (that is, <X extends SomethingElse>).

Collections.sort expects as its generics argument a <T extends Comparable<? super T>>. I fail to see where the super kicks in in there. Do you have a concrete example of why this is necessary?

While I am at it, I am deeply afraid that I don't understand the full implications of P either... I have read many, many links, without having had a clear, obvious proof that P is P and C is C...

EDIT As to the may already have an answer here": no, sorry. I have read this link, and many others on SO. This still does not tell me the core mechanism behind it all. The two answers given to me so far give me hints, in fact more so than all the links I could find so far.

回答1:

E.g.

List<Interger> myIntegers = Arrays.asList(5, 2, 3);

List<Long> myLongs = Arrays.asList(5L, 2L, 3L);

MyNumberComparator myNumberComparator = new Comparator<Number>(){...}

Collections.sort(myIntegers, myNumberComparator ); // Number is "super" class of Integer
Collections.sort(myLongs , myNumberComparator ); // Number is "super" class of Long

So "super" here allows to reuse MyNumberComparator for both sorting Integers and sorting Longs.



回答2:

I fail to see where the super kicks in in there. Do you have a concrete example of why this is necessary?

Say you have a class Animal, which is comparable to all Animals:

public class Animal implements Comparable<Animal>

Now let's say you have a class Dog, which extends Animal:

public class Dog extends Animal

Now the question is, can Dog compare to another Dog? (i.e. can you do myDog.compareTo(yourDog)) The answer is of course. A Dog, as an Animal, is comparable to all Animals, including Dogs (as well as Cats).

However, Dog does not implement Comparable<Dog>, so a bound T extends Comparable<T> would not work for T = Dog.

But for sorting all we care is that the type can compare to itself (which Dog can do). So the suitable least restrictive bound is T extends Comparable<? super T>, which does work for Dog.



回答3:

Try to create a List of Number :

List<Number> list = new ArrayList<Number>(Arrays.asList(2, 3.14, 5, 0, 42, 2.5));

Now try to sort it :

Collections.sort(list);

Looking at the generic argument <T extends Comparable<? super T>>, it equivalent in this case to <Number extends Comparable<? super Number>>. However the Number class doesn't implement such a comparator. Hence the code does'nt compile and it forces you to create your own one.