I noticed the specificaition for Collections.sort:
public static <T> void sort(List<T> list, Comparator<? super T> c)
Why is the "? super" necessary here? If ClassB extends ClassA, then wouldn't we have a guarantee that a Comparator<ClassA> would be able to compare two ClassB objects anyway, without the "? super" part?
In other words, given this code:
List<ClassB> list = . . . ;
Comparator<ClassA> comp = . . . ;
Collections.sort(list, comp);
why isn't the compiler smart enough to know that this is OK even without specifying "? super" for the declaration of Collections.sort()?
Josh Bloch had a talk at Google I/O this year, called Effective Java Reloaded, which you may find interesting. It talks about a mnemonic called "Pecs" (producer extends, consumer super), which explains why you use ? extends T and ? super T in your input parameters (only; never for return types), and when to use which.
There's a really nice (but twisty) explanation of this in More Fun with Wildcards.
This is similar to C#, I just learned about it a couple days ago as to why (the hard way, and then the PDC informative way).
Assume Dog extends Animal
Blah<Dog> is not the same as Blah<Animal> they have completely different type signatures even though Dog extends Animal.
For example assume a method on Blah<T>:
T Clone();
In Blah<Dog> this is Dog Clone(); while in Blah<Animal> this is Animal Clone();.
You need a way to distinguish that the compiler can say that Blah<Dog> has the same public interface of Blah<Animal> and that's what <? super T> indicates - any class used as T can be reduced to its super class in terms of Blah<? super T>.
(In C# 4.0 this would be Blah<out T> I believe.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With