我们可以ArrayList<? extends My_Class>
在哪里,因为如果您以这种方式声明它,它将不允许您添加任何新元素:
ArrayList<? extends My_Class> obj=new ArrayList<? extends My_Class>();
list.add(new Derived_My_Class()); //this is compilation error
答案 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)很好地解释了这个问题