java使用两种类型向通用列表添加对象
我读了几篇文章,比如here,但我找不到解决问题的办法
为什么我不能添加d?它是对象的一个子类型。。。
d的类型:A<B<X>>
List<A<B<? extends Object>>> rv=new LinkedList<>();
rv.add(d); //not working
编辑
我试图简化这个问题。当我这样做时:
A<B<?>> abcv=new A<B<String>>();
我得到错误:类型不匹配:无法从A<B<String>> to A<B<?>>
转换
但是,字符串与“?”兼容那么为什么它不起作用呢?我想将元素添加到列表中,最后一个类型可以通过任何方式进行选择,如下所示:
List<A<B<?>>> rv=new LinkedList<>();
rv.add(new A<B<X>>());
rv.add(new A<B<String>>());
rv.add(new A<B<Integer>>());
# 1 楼答案
??泛指任何类型
例如:
可以将任何类型的泛型列表分配给
List<?>
,但不能将任何类型的对象添加到列表中,因为编译器不知道它是什么类型,因为通配符(?)<?>
通配符允许分配任何类型的列表,但add()方法在该列表上无效,因为可能会将错误类型的内容放入集合中。由于通配符(?),编译器不知道要传递哪种类型如果您想将任何类型的对象添加到列表中,您可以像这样获取列表
现在编译器知道rv是只接受对象类型的列表,所以编译器不会抱怨任何事情
# 2 楼答案
List<SubClaz>
在Java中不是List<SuperClaz>
的子类型。这就是为什么使用通配符:List<SubClaz>
是List<? extends SuperClaz>
的一个子类型现在来看你的
A<B<?>> abcv=new A<B<String>>();
示例:通过添加通配符,您使
B<String>
成为了B<?>
的子类型,但是由于它们也被另一个类型A
包装,我们回到了第一个问题:A<B<String>>
不是A<B<?>>
的子类型 (注意
B<?>
是SuperClaz
,在本例中B<String>
是SubClaz
)你可以用同样的方法解决这个问题;通过添加另一个通配符:
A<B<String>>()
是A<? extends B<?>>
的一个亚型请记住,这不允许您根据需要阅读或操作列表。搜索协方差和逆变换以获取更多详细信息。这里有一个很好的例子:http://bayou.io/draft/Capturing_Wildcards.html
# 3 楼答案
d
应具有类型A<B<? extends Object>>
或兼容类型