5

我有一个接口A,该类B实现。

以下通用方法有效

public static <T, U extends T> List<T> listFactory(Collection<U> source) {
    return new ArrayList<T>(source);
}

public static <T> List<T> listFactory(Collection<? extends T> source) {
    return new ArrayList<T>(source);
}

没有(编译错误,类型不匹配),当我将输出定向到

List<A> tester = listFactory(B.defaultCollectionFactory(3));

defaultCollectionFactory(int count)静态提供Bs 的集合,带有默认的标签方案。

关于为什么会这样的任何见解?似乎通用 U 和通配符在做同样的事情。

4

2 回答 2

4

编译器为该listFactory方法推断出与您预期不同的类型参数。它推断T是类型B,所以签名是有效的List<B> listFactory(Collection<? extends B> source)A通过在方法调用中显式指定类型参数:

List<A> tester = Test.<A> listFactory(B.defaultCollectionFactory(3));
于 2009-10-03T19:34:27.440 回答
2

在第一个构造中,您指定要返回List传入项的接口的 a。您指定传入的 Object 与 U extends T方向上的返回 Object 类型之间的关系。在这种情况下,编译器可以分别关联ABTU

在第二种情况下,没有这样的区别,因此编译器假定T引用B并将返回值键入为List<B>。然后你就会掉入陷阱,虽然B是 的实例A,但List<B>不是 的实例List<A>。编译器会抱怨:

类型不匹配:无法从 List<B> 转换为 List<A>

您会发现,对于第一个构造,您可以自由地指定List任何接口的B实现或B层次结构中的任何超类(List<Object>例如),编译器不会抱怨。

于 2009-10-03T19:27:25.567 回答