什么是 < ? super T > 语法?

我无法理解下面的语法:

public class SortedList< T extends Comparable< ? super T> > extends LinkedList< T >

我看到 SortedList 类扩展了 LinkedList。我只是不知道是什么

T extends Comparable< ? super T>

手段。

到目前为止,我对它的理解是,类型 T 必须是一个实现可比较的类型... ... 但是什么是 < ? super T >

83980 次浏览

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


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"

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

Consider the following example:

  1. Using a type parameter defined in the class declaration

    public class ArrayList extends AbstractList ... {
    public boolean add(E o) // You can use the "E" here ONLY because it's already been defined as part of the class

  2. Using a type parameter that was NOT defined in the class declaration

    public <T extends Animal> void takeThing(ArrayList<T> list)
    // Here we can use <T> because we declared "T" earlier in the method declaration
    

    If the class itself doesn't use a type parameter, you can still specify one for a method, by declaring it in a really unusual (but available) space - before the return type. This method says that T can be "any type of Animal".

NOTE:

public <T extends Animal> void takeThing(ArrayList<T> list)


is NOT same as


public void takeThing(ArrayList<Animal> list)

Both are legal, but they are different. The first one indicates that you can pass in a ArrayList object instantiated as Animal or any Animal subtype like ArrayList, ArrayList or ArrayList. But, you can only pass ArrayList in the second, and NOT any of the subtypes.

It means that the type T must implement Comparable of T or one of its super classes.

For example, if A extends B, if you want to use SortedList<A>, A must implement Comparable<A> or Comparable<B>, or in fact just Comparable.

This allows the list of As to be constructed with any valid comparator.