Java泛型好奇心
作者:互联网
我有一个接口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)静态提供B的集合,具有默认的标签方案.
关于为什么会这样的任何见解?看起来普通的U和通配符正在做同样的事情.
解决方法:
在第一个构造中,您指定要返回传入的项的接口的List.指定传入的Object与U extends T方向的返回Object类型之间的关系.在这种情况下,编译器可以分别将A和B与T和U相关联.
在第二种情况下,没有这种区别,因此编译器假定T指向B并且将返回值键入List< B>.然后你陷入陷阱,尽管B是A的实例,List< B>不是List< A>的实例.编译器会抱怨:
Type mismatch: cannot convert from List<B> to List<A>
您将发现,使用第一个构造,您可以自由地指定B实现的任何接口的List或B层次结构中的任何超类(例如,List< Object>),并且编译器不会抱怨.
标签:java,collections,generics,bounded-wildcard 来源: https://codeday.me/bug/20190522/1151588.html