为什么 Java PriorityQueue 实现使用 Comparator<? super E> 而不是简单的 Comparator<E>

Why does the Java PriorityQueue implementation use Comparator<? super E> and not simply Comparator<E>

jdk8中定义的JavaPriorityQueue源码使用了这样定义的比较器

    /**
     * The comparator, or null if priority queue uses elements'
     * natural ordering.
     */
    private final Comparator<? super E> comparator;

源代码here(第 108 行)

为什么需要使用 E 的超类型而不是简单的 E。

换句话说,为什么不像下面这样定义比较器:

    private final Comparator<E> comparator;

额外抽象背后的动机是什么?

因为为什么不。

给定一个可以比较任何 2 个 CharSequence 对象的比较器(CharSequence 是一个接口;String、StringBuilder 和其他一些实现它的东西),然后..当你只需要比较时,这同样好字符串。所有的字符串也是 CharSequences,所以一个比较器可以告诉你对于任何 2 个字符序列对象,哪个 'comes first' 可以完美地完成这项工作。

泛型在默认情况下是不变的,所以如果你有一个 PriorityQueue<String>,并且它像你想要的那样工作,它看起来像 Comparator<E>,这意味着 Comparator<String>,并且Comparator<CharSequence> 不兼容。就像将 String 传递给需要 Integer 对象的方法一样,它不会编译。

因此,<? super E> 这样您 就可以 传递一个 Comparator<CharSequence>

当然,它不常出现,但 'more correct' 是这样的。我敢肯定,如果您碰巧有一个 CharSequences 的比较器,但不能用它来为 PriorityQueue<String>.

供电,您一定会感到惊讶。