问题描述
刚刚完成了 Java 7 的 java.util.Collections
类的实现,看到了一些我不明白的东西.在max
函数签名中,为什么T
受Object
的约束?
Just went through the implementation of Java 7's java.util.Collections
class, and saw something that I don't understand. In the max
function signature, why is T
bounded by 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
似乎工作正常.
max
seems to work fine if the Object bound is omitted.
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;
}
实际上在任何情况下边界都会产生影响吗?如果是,请提供一个具体的例子.
Are there actually any situations where the bound makes a difference? If yes, please provide a concrete example.
推荐答案
两者有相同的界限,但有细微的差别.
The two have the same bounds but there is a subtle difference.
<T extends Object & Comparable<? super T>>
这将导致 T
成为被擦除的 Object
.
This will cause T
to become an Object
under erasure.
<T extends Comparable<? super T>>
这将导致 T
在擦除时变为 Comparable
.
This will cause T
to become Comparable
under erasure.
在这种情况下这样做是因为 .max
早于 Java 5.我们可以在 此链接 Joachim 亲切地提供了 Java 1.4 中 .max
的签名.2 是:
In this case it is done because .max
predates Java 5. We can see in this link Joachim kindly provided that the signature of .max
in Java 1.4.2 is:
public static Object max(Collection coll)
我们是否使用了 作为绑定,我们的签名是
Had we used <T extends Comparable<? super T>>
as a bound, our signature would be
public static Comparable max(Collection coll)
这会破坏 API.我设法找到了 此页面,讨论了转换旧 API到通用的,它给出了 .max
作为一个具体的例子.
Which would break the APIs. I've managed to find this page that discusses converting old APIs to generic ones and it gives .max
as a specific example.
这里解释了为什么 max
是这样定义的:
Here they explain why max
is defined this way:
您还需要确保修订后的 API 保留与旧客户端的二进制兼容性.这意味着 API 的擦除必须与原始的、未衍生的 API 相同.在大多数情况下,这自然会发生,但也有一些微妙的情况.我们将研究我们遇到的最微妙的情况之一,方法 Collections.max()
.正如我们在使用通配符更有趣的部分中看到的,max()
的一个似是而非的签名是:
public static >T max(Collection<T> coll)
这个没问题,只不过这个签名的擦除是:public static Comparable max(Collection coll)
与max的原始签名不同(): public static Object max(Collection coll)
public static <T extends Comparable<? super T>> T max(Collection<T> coll)
This is fine, except that the erasure of this signature is: public static Comparable max(Collection coll)
which is different than the original signature of max(): public static Object max(Collection coll)
当然可以为 max() 指定此签名,但没有完成,所有调用 Collections.max() 的旧二进制类文件都依赖于返回 Object 的签名.
One could certainly have specified this signature for max(), but it was not done, and all the old binary class files that call Collections.max() depend on a signature that returns Object.
这篇关于为什么 T 在 Collections.max() 签名中受 Object 的限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!