[英]Collections.max method type parameters declaration signature <T extends Comparable<? super T>> explanation
[英]Explanation of the Collections.max signature
當我偶然發現這個方法簽名時,我正在閱讀一篇關於 Java 泛型的文章:
static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll);
我不明白的部分是為什么我們需要擁有
Collection<? extends T> coll
不會
Collection<T> coll
也是嗎?
有人可以解釋為什么下面的簽名是不夠的嗎?
static <T extends Object & Comparable<? super T>> T max(Collection<T> coll);
提前感謝您的回復。 這讓我困惑了很長一段時間。。
加博爾是對的。 通配符允許返回對象的靜態類型與您輸入的集合的聲明參數類型不同。 例如,給定這些類:
interface S extends Comparable<S> {}
class A implements S {
@Override
public int compareTo(final @NotNull S o) {
return 0;
}
}
class B implements S {
@Override
public int compareTo(final @NotNull S o) {
return 0;
}
}
而這個類:
class Test {
@Nullable
static <T extends Comparable<? super T>> T extendsMax(
Collection<? extends T> coll) {
return null;
}
@Nullable
static <T extends Comparable<? super T>> T max(Collection<T> coll) {
return null;
}
}
觀察哪些調用 compile 哪些調用不調用:
public static void main(String[] args) {
final Collection<S> sColl = new ArrayList<>();
final Collection<A> aColl = new ArrayList<>();
final Collection<B> bColl = new ArrayList<>();
final S s1 = Test.<S> extendsMax(sColl); // compiles, T = S, <? extends T> = S
final S s2 = Test.<S> extendsMax(aColl); // compiles, T = S, <? extends T> = A
final S s3 = Test.<S> extendsMax(bColl); // compiles, T = S, <? extends T> = B
final A a1 = Test.<A> extendsMax(aColl); // compiles, T = A
final B b1 = Test.<B> extendsMax(bColl); // compiles, T = B
final S s4 = Test.<S> max(sColl); // compiles, T = S
final S s5 = Test.<S> max(aColl); // does not compile, T = S, T != A
final S s6 = Test.<S> max(bColl); // does not compile, T = S, T != B
final S s7 = Test.max(aColl); // compiles, but because T = A, and A
// can be assigned to S
}
所以通配符允許一些靈活性。 雖然您可以省略通配符(老實說,我想不出需要通配符的地方),但它存在是有原因的。
湯姆也是不正確的。 您可以使用通配符向集合添加null
(如果集合首先支持add()
):
List<? extends Number> list = new ArrayList<>();
list.add(null); // compiles, and should execute just fine
因為add()
、 remove()
和Collection
接口中的大多數其他修改器都是可選操作,所以如果參數只是聲明為Collection
那么通過這些方法改變集合無論如何都是不安全的。 此外,通常可以使用iterator().remove()
或類似的東西從集合中刪除元素,而不管它們是否使用通配符聲明,尤其是對於已經包含在 Java 集合框架中的元素。
因此,雖然通配符確實限制了您可以對集合執行的操作,但不應將其用作防止更改集合的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.