Java泛型
我是generics的新手,有接受A的孩子作为参数的列表。
我写了下面的代码,问题的底部有一个错误。任何帮助表示赞赏。
abstract class A{
..
}
class A1 extends A{
..
}
class A2 extends A{
..
}
我想声明一个列表
public class Model{
private List<? extends A> items;
public <S extends A> void add(S item){
items.add(item); // error on this line
}
}
答案 0 :(得分:0)
这是因为泛型不变。
private List<? extends A> items;
public <S extends A> void add(S item) {
items.add(item);
}
使用<? extends A>
并不代表&#34; A
&#34; 的任何子类型,但您实际上是说 &#34;属于A
&#34; (或A
本身)的子类型的未知类型。您正尝试将类型S
的项添加到列表中,但S
可以是与未知类型不同的类型。
让我通过以下类比来解释它。底线是:Cat
是Animal
,Dog
也是Animal
,但Cat
不是 a Dog
。
假设我有一个<? extends Animal>
的列表。这可以是Dog
的列表,但它也可以是Cat
或Bird
的列表,或者是Animal
的子类型的任何类型。随你。我们不在乎。
那我们在这里有什么?
public <S extends Animal> void add(S item) {
this.items.add(item);
}
S
是Animal
的某个子类型,但编译器并不知道哪种类型。可能items
仅包含Bird
,我们正在尝试添加Cat
。 将猫添加到鸟类列表意味着麻烦,不是吗? items
的类型参数根本未知。我们无法将Cat
添加到Dog
列表中,因此会出错。
只需删除通配符......
List<A> items;
public void add(A item) {
this.items.add(item);
}
...或使该类具有通用性:
class Model<T> {
List<T> items;
public void add(T item) {
this.items.add(item);
}
}
答案 1 :(得分:-1)
为什么不使用以下语法而不是泛型?
public class Model
{
private List<A> items ;
public void add(A item)
{
}
}