这个问题问得好。首先,让我们从
Collections使用诸如
binarySearch(List<? extends Comparable<? super T>> list, T key)
确实,为什么不只是
binarySearch(List<? extends Comparable<T>> list, T key)
这样做的原因是PECS原则:生产者扩展,消费者超级。怎么
binarySearch办?它从列表中 读取 元素,然后通过 将 其值 传递
给
compareTo函数进行比较。由于列表读取元素,因此它充当了生产者,因此,第一部分即生产者扩展。这很明显,那么“超级消费者”部分又如何呢?
Consumer
Super本质上意味着,如果仅要将值传递给某个函数,则不必在乎它是否接受对象的确切类型还是对象的某些超类。因此,
binarySearch声明的意思是:只要可以将任何内容传递给
compareTolist元素的方法,我都可以查找任何内容。
在排序的情况下,并不是很明显,因为仅将元素相互比较。但是即使那样,如果
base实际上实现了
Comparable<base>(整个比较是否完成)
A并且
B仅仅扩展
base而又不以任何方式进行比较又会怎样呢?然后,您将无法对
A和的列表进行排序,
B因为它们分别未实现
Comparable<A>和
Comparable<B>。每次子类化时,您都必须重新实现整个接口!
另一个例子:如果有人想对包含某个类实例甚至不扩展您的实例的列表进行二进制搜索,该怎么办
base?
class baseComparable implements Comparable<base> { private final base key; // other fields baseComparable(base key, ...) { this.key = key; // other fields initialization } @Override public int compareTo(base otherKey) { return this.key.compareTo(otherKey); }};现在,他们希望使用的实例
A作为此二进制搜索的关键字。由于
? super T部分原因,他们只能这样做。请注意,此类不知道键是a
A还是a,
B因此无法实现
Comparable<A/B>。
至于您的示例,我想这只是一个糟糕的设计示例。不幸的是,我认为在不破坏PECS原理和/或限制Java泛型已经有限的功能的情况下,无法防止此类情况。



