Collections.sort 泛型方法签名

Collections.sort generic method signature

在java.util.Collections里面我们有下面的方法签名

public static <T> void sort(List<T> list, Comparator<? super T> c) 

我不明白为什么有人会指定

Comparator<? super T>

而不是

Comparator<T>

它涵盖了哪些用例?

这是一个例子:

class Person {}

class Student extends Person {}

? super T 表示 ?T 的超类(或接口)。 也就是说,如果比较器是 Comparator<Person>,因为 Student 是从 Person 继承的,所以这个比较器应该仍然可以在 Student.

上工作
List<Student> students = ...
Collections.sort(students, new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        // compare person
        return 0;
    }
});

如果我们把Comparator<? super T>改成Comparator<T>,上面的代码将无法编译。

// A
public static <T extends Comparable<? super T>> void sortA(List<T> list) 

// B
public static <T extends Comparable<T>> void sortB(List<? extends T> list)

这些签名不同是因为它们对类型 T 和 T 定义中 Comparable 的类型参数之间的关系提出了不同的要求。

例如假设您有这个 class:

class A implements Comparable<Object> { ... }

那么如果你有

List<A> list = ... ;
sortA(list); // works
sortB(list); // fails

sortA 失败的原因是没有类型 T 既可与自身相比较,也可以是列表类型的超类型。