Java泛型好奇心

Car*_*arl 5 java generics collections bounded-wildcard

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

以下通用方法有效

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

public static <T> List<T> listFactory(Collection<? extends T> source) {
    return new ArrayList<T>(source);
}
Run Code Online (Sandbox Code Playgroud)

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

List<A> tester = listFactory(B.defaultCollectionFactory(3));
Run Code Online (Sandbox Code Playgroud)

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

关于为什么会这样的任何见解?看起来普通的U和通配符正在做同样的事情.

akf*_*akf 2

在第一个构造中,您指定要返回List传入项目的接口。您指定传入的 Object 和返回的 Object 类型之间的关系 U extends T。在这种情况下,编译器可以分别将AandBTand关联起来U

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

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

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