Java 泛型:列表<;?扩展动物>;与列表相同<;动物>;?
我只是想理解Java泛型中的Java 泛型:列表<;?扩展动物>;与列表相同<;动物>;?,java,generics,covariance,extends,contravariance,Java,Generics,Covariance,Extends,Contravariance,我只是想理解Java泛型中的extends关键字 ListList是List的一个子类型,而不是列表表示分配给此变量的值必须是“类型”列表。然而,这并不意味着必须只有Animal对象,也可以有子类 List<Number> l = new ArrayList<Number>(); l.add(4); // autoboxing to Integer l.add(6.7); // autoboxing to Double 这不是您期望的列表,不是列表。但是如果你用List
extends
关键字
ListList
是List的一个子类型,而不是<代码>列表
表示分配给此变量的值必须是“类型”列表
。然而,这并不意味着必须只有Animal
对象,也可以有子类
List<Number> l = new ArrayList<Number>();
l.add(4); // autoboxing to Integer
l.add(6.7); // autoboxing to Double
这不是您期望的列表
,不是列表
。但是如果你用List
写List,你就知道你拥有的绝对是一个动物列表。它们不一定都是“动物的”——它们也可以是派生类型。例如,如果你有一个动物列表,一对夫妇可能是山羊,其中一些是猫,等等,这是有道理的,对吗
例如,这是完全有效的:
List<Animal> aL= new List<Animal>();
aL.add(new Goat());
aL.add(new Cat());
Animal a = aL.peek();
a.walk(); // assuming walk is a method within Animal
使用listhmm。。明白了。很好的解释是+1“这实际上不是我可以持有的对象类型的声明。这是一个关于我可以引用哪些类型的列表的声明。”并且出于同样的原因,你不能做L.add(new Goat())
因为在第一个示例中,我可能引用的是一个不能添加Goat的狗的列表:),如果您将列表传递给List@DonLi:的确如此。这就是为什么我使用“如果您被允许…”的原因,即在假设的场景中,编译器认为List
是List
的子类型。为什么不使用void foo(List参数)
?
void mySub(List<? extends Animal> myList) {
myList.add(new Cat()); // compile error here
Animal a = myList.get(0); // works fine
}
void mySub(List<? super Animal> myList) {
myList.add(new Cat()); // works fine
Animal a = myList.get(0); // compile error here, since the list entry could be a Plant
}
List<Number> l = new ArrayList<Number>();
l.add(4); // autoboxing to Integer
l.add(6.7); // autoboxing to Double
public void doSomethingWith(List<Number> l) {
...
}
List<Double> d = new ArrayList<Double>();
doSomethingWith(d); // not working
public void doSomethingWith(List<? extends Number> l) {
...
}
List<Double> d = new ArrayList<Double>();
doSomethingWith(d); // works
List<Animal> aL= new List<Animal>();
aL.add(new Goat());
aL.add(new Cat());
Animal a = aL.peek();
a.walk(); // assuming walk is a method within Animal
aL.peek().meow(); // we can't do this, as it's not guaranteed that aL.peek() will be a Cat
List<? extends Animal> L;
L = aL; // remember aL is a List of Animals
L.add(new Animal()); // throws a compiletime error
List<Goat> gL = new List<Goat>(); // fine
gL.add(new Goat()); // fine
gL.add(new Animal()); // compiletime error