我以前曾问过这个问题,但从来没有找到解决方案。
我正在尝试将子类型添加到如下定义的列表中。这应该是100%合法的,子类型扩展主要类型。
private List<? extends TopBean> beans;
public List<? extends TopBean> getBeans() {
return beans;
}
我正在尝试这样做:
this.getBeans().add(new SecondaryBean());
SecondaryBean扩展TopBean (不是直接但在某种程度上)。
这让我疯了 - 错误是
The method add(capture#2-of ? extends TopBean) in the type List<capture#2-of ? extends TopBean> is not applicable for the arguments (SecondaryBean)
如果我将它转换为TopBean,同样的错误,只是措辞不同
Ťhe method add(capture#2-of ? extends TopBean) in the type List<capture#2-of ? extends TopBean> is not applicable for the arguments (TopBean)
我必须将子SecondaryBean添加到通用TopBeans列表中。该怎么办?
答案 0 :(得分:3)
你不能将任何非null添加到以这种方式定义的外卡。
如果你已经定义了它
List<? super TopBean>
然后添加任何扩展TopBean的东西是可能的,但获取是一个不同的故事 - 只有TopBean扩展或实现的东西
我不明白为什么你首先将列表定义为通配符,将其定义为List似乎可以为您提供所需的一切。方法有时应该用wikdcards定义,而不是数据成员
答案 1 :(得分:0)
基本上你的声明是错误的。不要在变量声明或返回类型中使用通配符。仅对方法参数使用通配符。
private List<TopBean> beans;
public List<TopBean> getBeans() {
return beans;
}
可能有很多原因和讨论为什么你不在任何地方使用外卡而是方法参数,但这是我个人的一般规则。它过于简单化,但将涵盖Java中所有现实世界中泛型的90%-99%。
现在通过上面给出的代码,您可以将TopBean添加到列表或TopBean的任何子类中。
答案 2 :(得分:0)
我解决了这个问题。在下面的演员阵容中,错误消失了(有警告,但我可以忍受)。
((List<SecondaryBean>)this.getBeans()).add(new SecondaryBean());
我保证有一个SecondaryBeans列表,所以这是安全的。