假设我有一个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>();


在这两种情况下,您都可以添加GeneralBudgetYearBeanSubBudgetYearBean对象。

10-06 04:05