我们在哪里可以使用ArrayList< ?扩展My_Class>

时间:2012-07-26 12:28:06

标签: java generics

我们可以ArrayList<? extends My_Class>在哪里,因为如果您以这种方式声明它,它将不允许您添加任何新元素:

ArrayList<? extends My_Class> obj=new ArrayList<? extends My_Class>();
list.add(new Derived_My_Class()); //this is compilation error

3 个答案:

答案 0 :(得分:5)

用于描述这些关键字的广泛使用的首字母缩略词是:PECS:制作人扩展 - 消费者超级。

因此,如果您使用“extends”,您的集合会生成给定类型的元素。所以你不能添加它,你只能从中获取它。

一个示例用法是为API的客户提供一个列表:

public List<? extends CharSequence> getFoo() {
    List<String> list = new ArrayList<String>();
    list.add("foo");
    return list;
}

相关:Java generics: Collections.max() signature and Comparator

答案 1 :(得分:2)

你是对的,你的ArrayList不能按照它的推导方式使用:没有任何东西你可以投入其中。

您希望存储My_Class及其子类只需ArrayList<My_Class>;它将正确地获取My_Class及其所有DerivedClass的对象。

答案 2 :(得分:0)

嗯......没有必要像这样宣布ArrayList,而是通过写作来填补你的意图

的ArrayList&LT;超型&GT; obj = new ArrayList&lt;超型&GT;();

根据我的观点,我在方法参数中看到了这个概念,你期望你的调用者提供特定超类型的子类型的集合(或者像上面某人所说的那样从方法返回)。如下所示

public getAnimals(List< ? extends Animal> obj){

obj.add(something);    //not allowed

}

你有可能在你的某些类型的名单中添加驴,猴子和鸟类等(猴子)。从中得到classCastException。

这就是为什么在这种情况下不允许的原因。阅读Josh Bloch撰写的Effective Java。他用生产者消费者类比(PECS)很好地解释了这个问题