假设我有一个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
对象。