[英]Java Generics & Inheritance: Unable to add to List
假设我有一个List定义,如下所示。
private List<? extends GeneralBudgetYearBean> budgetYearBeans;
// + Getters/setters...
为什么在本课之外,我通常无法按以下方式引用此列表:
GeneralBudgetYearBean gbyb;
getBudgetYearBeans().add(bgyb);
错误是:
The method add(capture#6-of ? extends GeneralBudgetYearBean) in the type List<capture#6-of ? extends GeneralBudgetYearBean> is not applicable for the arguments (GeneralBudgetYearBean)
这没有道理。 是否因为“?extends T”与“ T”不同,并且不能在此处替换“ T”?
我需要通常能够在没有细节的情况下操纵此类。 在某个时候,将在扩展类中构造一个“ SUBGeneralBudgetYearBeans”的ArrayList,这就是为什么我需要使用“?extended GeneralBudgetYearBean”表示法的原因。
根据PESC原则:
当只需要获取对象时,使用扩展;当只需要添加对象时,使用扩展。
就您而言,
private List<? extends GeneralBudgetYearBean> budgetYearBeans;
是生产者 ,这意味着列表将只能产生元素。 原因是在编译时,编译器不知道GeneralBudgetYearBean的子类型,这就是为什么它不让您添加元素的原因,因为不能完全确定是否允许您。
由于您还将(在某个时候)添加SubBudgetYearBean
对象(我相信这是GeneralBudgetYearBean
子类),因此您必须将列表创建为使用者 。 因此,这将为您工作:
private List<? super SubBudgetYearBean> budgetYearBeans;
在这种情况下,您将能够实例化budgetYearBean
为:
budgetYearBeans = new ArrayList<Object>();
budgetYearBeans = new ArrayList<GeneralBudgetYearBean>();
在这两种情况下,您都可以添加GeneralBudgetYearBean
和SubBudgetYearBean
对象。
当您使用表达式List<? extends GeneralBudgetYearBean> budgetYearBeans;
List<? extends GeneralBudgetYearBean> budgetYearBeans;
,您告诉编译器该变量以后将收到一个List,其中X将扩展GeneralBudgetYearBean
。 但是它不知道它将是什么类,因此,如果不允许,则不能在其中添加任何内容。
您可以使当前类通用:
class xxx<T extends GeneralBudgetYearBean> {
private List<T> budgetYearBeans; // getter and setter
然后,您将被允许做:
T gbyb;
getBudgetYearBeans().add(bgyb);
因为现在您告诉编译器:您不完全知道它将是什么,但是会是同一回事。
删除通配符,在这种情况下它们不会真正为您提供帮助,它们只会使事情复杂化,除非您真的知道自己在做什么。
private List<GeneralBudgetYearBean> budgetYearBeans = ...
public List<GeneralBudgetYearBean> getBudgetYearBeans() {
return budgetYearBeans;
}
因为SUBGeneralBudgetYearBean
扩展了GeneralBudgetYearBean
,所以将它们添加到列表中一个都没有问题。
SUBGeneralBudgetYearBean sgyb = ...
getBudgetYearBeans().add(sgyb);
...或作为清单...
List<SUBGeneralBudgetYearBean> sgybs = ...
getBudgetYearBeans().addAll(sgybs);
看到? 实际上不需要通配符。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.