为什么T在Collections.max()签名中受Object约束?
刚刚通过Java 7的java.util.Collections
类的实现,并看到了我不明白的东西。 在max
函数签名中,为什么T
以Object
为界?
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) { Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while (i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
如果省略对象的限制, max
似乎工作正常。
public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll) { Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while (i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
实际上是否有任何情况下的界限有所作为? 如果是,请提供一个具体的例子。
两者有相同的界限,但有一个微妙的差异。
<T extends Object & Comparable<? super T>>
这将导致T
成为一个被删除的Object
。
<T extends Comparable<? super T>>
这将导致T
在擦除之后变成Comparable
。
在这种情况下,它完成是因为.max
早于Java 5.我们可以在这个链接中看到Joachim友好地提供了在Java 1.4.2中.max
的签名是:
public static Object max(Collection coll)
如果我们用<T extends Comparable<? super T>>
<T extends Comparable<? super T>>
作为绑定,我们的签名将是
public static Comparable max(Collection coll)
这将打破API。 我已经设法find这个页面 ,讨论转换旧的API为通用的,它给.max
作为一个具体的例子。
这里他们解释了为什么max
是这样定义的:
您还需要确保修订后的API保持与旧客户端的二进制兼容性。 这意味着API的删除必须与原始的未经缩减的API相同。 在大多数情况下,这是自然而然的,但也有一些微妙的情况。 我们将检查我们遇到的最微妙的情况之一,方法
Collections.max()
。 正如我们在通配符更多乐趣一节中看到的,max()
的合理签名是:
public static <T extends Comparable<? super T>> T max(Collection<T> coll)
public static <T extends Comparable<? super T>> T max(Collection<T> coll)
这很好,除了这个签名的删除是:public static Comparable max(Collection coll)
,它与max()的原始签名不同:public static Object max(Collection coll)
当然可以为max()指定这个签名,但是没有完成,所有调用Collections.max()的旧二进制类文件都依赖于返回Object的签名。