刚刚完成了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;
}
如果省略Object绑定, 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;
}
实际上是否存在绑定产生影响的任何情况?如果是,请提供一个具体的例子。
答案 0 :(得分:84)
两者具有相同的界限,但 是一个微妙的差异。
<T extends Object & Comparable<? super T>>
这会导致T
在删除后成为Object
。
<T extends Comparable<? super T>>
这会导致T
在删除后成为Comparable
。
在这种情况下,它完成是因为.max
早于Java 5.我们可以在this link中看到Joachim,请注意Java 1.4.2中.max
的签名是:
public static Object max(Collection coll)
如果我们使用<T extends Comparable<? super T>>
作为约束,我们的签名将是
public static Comparable max(Collection coll)
哪会破坏API。我设法找到了this page讨论将旧API转换为通用API的方法,并将.max
作为一个具体示例。
这里他们解释了为什么max
以这种方式定义:
您还需要确保修订后的API保留与旧客户端的二进制兼容性。这意味着API的擦除必须与原始的,未经过授权的API相同。在大多数情况下,这自然会失败,但有一些微妙的情况。我们将研究我们遇到的最微妙的案例之一,方法
Collections.max()
。正如我们在使用通配符更多乐趣部分中看到的那样,max()
的合理签名是:
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的签名。