为什么T在Collections.max()签名中受Object约束?

刚刚通过Java 7的java.util.Collections类的实现,并看到了我不明白的东西。 在max函数签名中,为什么TObject为界?

 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的签名。