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 consumer super"

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>