73

刚刚通过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;
}

实际上是否存在边界产生影响的情况?如果是,请提供一个具体的例子。

4

1 回答 1

88

两者具有相同的界限,但存在细微差别。

 <T extends Object & Comparable<? super T>> 

这将导致T成为Object欠擦除。

 <T extends Comparable<? super T>>

这将导致T擦除Comparable不足。


在这种情况下,它是在.maxJava 5 之前完成的。我们可以在这个链接中看到Joachim 好心地提供了.maxJava 1.4.2 中的签名是:

public static Object max(Collection coll)

如果我们用作<T extends Comparable<? super T>>绑定,我们的签名将是

public static Comparable max(Collection coll)

这会破坏 API。我设法找到了讨论将旧 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 的签名。

于 2013-10-21T07:23:30.120 回答