5

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

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

3 回答 3

5

描述这些关键字的广泛使用的首字母缩写词是:PECS:Producer extends - consumer super。

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

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

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

相关:Java 泛型:Collections.max() 签名和比较器

于 2012-07-26T12:30:14.737 回答
2

你是对的,你ArrayList不能以它的派生方式使用:你不能把任何东西放进去。

您想要存储My_Class的内容及其子类很简单ArrayList<My_Class>;它将正确地获取My_Class所有对象。DerivedClass

于 2012-07-26T12:32:25.247 回答
0

嗯...没有必要像这样声明 ArrayList ,而是您的意图将通过编写来实现

ArrayList<Supertype> obj=new ArrayList<Supertype>();

根据我的经验,我在方法参数中看到了这个概念,您希望调用者提供特定超类型的子类型的集合(或从方法返回,就像上面有人说的那样)。如下

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

obj.add(something);    //not allowed

}

很有可能您可以在特定类型的列表中添加驴、猴子和鸟类等(例如猴子)。并从中获取 classCastException 。

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

于 2012-07-26T12:33:45.970 回答