了解在Java集合类中使用泛型

M. *_*eif 4 java generics collections types

在查看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;
}
Run Code Online (Sandbox Code Playgroud)

我不完全理解这里使用泛型类型.据我所知,T是Object的子类型,它也必须实现Comparable接口,该接口也通过泛型参数进行参数化.可比状态的参数必须是T的一些超类型.由于我们有某种递归类型定义.

但这是我的问题:据我所知,Java中的每个类型都是Object的子类型,那么他们为什么要在T的定义中指定它呢?

fge*_*fge 6

这是出于向后兼容的原因.

使用泛型类型时,此泛型类型具有下限,例如:

<T extends Foo & Bar> void someMethod(T xxx)
Run Code Online (Sandbox Code Playgroud)

然后运行时签名someMethod将是:

void someMethod(Foo xxx)
Run Code Online (Sandbox Code Playgroud)

(好吧,参数名称不存在,但是你得到了图片).

现在, JDK 5 之前Collections.max()定义; 它的签名是:

public static Object max(Collection coll)
Run Code Online (Sandbox Code Playgroud)

在Java 5中,可以翻译为:

public static Object max(Collection<Object> coll)
Run Code Online (Sandbox Code Playgroud)

事情是,返回值max不能是Comparable......


当然,在这种情况下,增加了更多的困难:

  • 第二个下限本身就是一个通用类型;
  • 此外,它Comparable是PECS方式的"消费者"(因此Comparable<? super T>);
  • Collection作为参数传递可以具有任何类型的或者是T或任何延伸T,因此? extends T; 我们不关心实际的类型,只Collection保证返回至少是T的东西.

这解释了有点复杂的签名......