What is <? super T> syntax? [duplicate]
I'm having trouble understanding the following syntax:
public class SortedList< T extends Comparable< ? super T> > extends LinkedList< T >
I see that class SortedList extends LinkedList. I just don't know what
T extends Comparable< ? super T>
means.
My understanding of it so far is that type T must be a type that implements Comparable...but what is < ? super T >
?
super in Generics is the opposite of extends. Instead of saying the comparable's generic type has to be a subclass of T, it is saying it has to be a superclass of T. The distinction is important because extends tells you what you can get out of a class (you get at least this, perhaps a subclass). super tells you what you can put into the class (at most this, perhaps a superclass).
In this specific case, what it is saying is that the type has to implement comparable of itself or its superclass. So consider java.util.Date. It implements Comparable<Date>
. But what about java.sql.Date? It implements Comparable<java.util.Date>
as well.
Without the super signature, SortedList would not be able accept the type of java.sql.Date, because it doesn't implement a Comparable of itself, but rather of a super class of itself.
It's a lower-bounded wildcard.
JLS 4.5.1 Type Arguments and Wildcards
Wildcards are useful in situations where only partial knowledge about the type parameter is required. [...] An upper bound is signified by the syntax:
? extends B
where
B
is the upper bound. [...] it is permissible to declare lower bounds on a wildcard, using the syntax:? super B
where
B
is a lower bound.
A List<? super Integer>
, for example, includes List<Integer>
, List<Number>
, and List<Object>
.
Wildcards are used to make generics more powerful and flexible; bounds are used to maintain type safety.
See also
- Java language guide/Generics/More Fun with wildcards
As to how this is useful in <T extends Comparable<? super T>>
, it's when you have something like Cat extends Animal implements Comparable<Animal>
.
Look at the signature of Collections.sort
public static <T extends Comparable<? super T>> void sort(List<T> list)
Therefore, with a List<Cat> listOfCat
, you can now Collections.sort(listOfCat)
.
Had it been declared as follows:
public static <T extends Comparable<T>> void sort(List<T> list)
then you'd have to have Cat implements Comparable<Cat>
to use sort
. By using the ? super T
bounded wildcard, Collections.sort
becomes more flexible.
See also
-
Effective Java 2nd Edition, Item 28: Use bounded wildcards to increase API flexibility
- Also, PECS principle: "producer
extends
consumersuper
"
- Also, PECS principle: "producer
It means that T
must implement Comparable<T itself or one of T's superclasses>
The sense is that because SortedList
is sorted, it must know how to compare two classes of its generics T
parameter. That's why T
must implement Comparable<T itself or one of T's superclasses>