在查看 Java 的 Collection 类(OpenJDK 8_update40)后,我发现了以下方法:
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;
}
我不完全理解这里泛型的使用。据我所知, T 是 Object 的子类型,它还必须实现 Comparable 接口(interface),该接口(interface)也通过通用参数进行参数化。 Comparable 的参数声明必须是 T 的某种父类(super class)型。因此我们有某种递归类型定义。
但这是我的问题:据我所知,Java 中的每种类型都是 Object 的子类型,那么为什么他们指定 它在 T 的定义内?
最佳答案
这是为了向后兼容。
当你使用一个泛型类型并且这个泛型类型有下界时,比如:
<T extends Foo & Bar> void someMethod(T xxx)
然后是someMethod
的运行时签名将是:
void someMethod(Foo xxx)
(好吧,参数名称不存在,但你明白了)。
现在,Collections.max()
在 JDK 5 之前定义;它的签名是:
public static Object max(Collection coll)
在 Java 5 中,可以翻译为:
public static Object max(Collection<Object> coll)
问题是 max
的返回值不能是 Comparable
...
当然,这样的话,又增加了更多的困难:
- 第二个下限本身是一个泛型;
- 此外
Comparable
是 PECS 方式中的“消费者”(因此Comparable<? super T>
); Collection
作为参数传递的可以是任何类型T
或任何扩展T
的东西,因此? extends T
;我们不关心实际类型,只关心Collection
保证返回至少一个T的东西。
这解释了有点复杂的签名......
关于java - 了解 Java 集合类中泛型的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32632317/