Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is SomeClass<? super T> not equivalent to SomeClass<T> in Java generic types?

Tags:

java

generics

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()?

like image 576
Kip Avatar asked Oct 30 '08 18:10

Kip


3 Answers

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.

like image 136
Chris Jester-Young Avatar answered Sep 24 '22 20:09

Chris Jester-Young


There's a really nice (but twisty) explanation of this in More Fun with Wildcards.

like image 40
Bill the Lizard Avatar answered Sep 24 '22 20:09

Bill the Lizard


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.)

like image 30
cfeduke Avatar answered Sep 23 '22 20:09

cfeduke