Java 泛型通配符问题:List<?延伸A> [英] Java Generics WildCard Question: List<? extends A>
问题描述
假设我有这些类:Vehicle、Car 和 Spaceship:
Let's say I have these classes : Vehicle, Car and Spaceship:
class Vehicle{
void rideVehicle(Vehicle v){
System.out.println("I am riding a vehicle!");
}
}
class Car extends Vehicle{
void rideVehicle(Vehicle c){
System.out.println("I am riding a car!");
}
}
class SpaceShip extends Vehicle{
void rideVehicle(Vehicle c){
System.out.println("I am riding a spaceship!");
}
}
我写了这个方法 addCars:
and I write this method addCars:
private static void addCars(List<? extends Vehicle> vcls){
vcls.add(new Car());
vcls.add(new Car());
vcls.add(new Car());
}
为什么我会收到编译时错误??我知道 List 是扩展 Vehicle 的任何 X 的 List 的超类型.对吗?
Why do I get a compile time error?? I understand that List is a supertype of List for any X that extends Vehicle. right?
谢谢
我得到的错误(编译时):类型列表中的方法 add(capture#2-of ? extends Vehicle) 不适用于参数 (Car).
the error I get (compile-time) : The method add(capture#2-of ? extends Vehicle) in the type List is not applicable for the arguments (Car).
推荐答案
方法参数在子类型中是逆变的,并且根据通配符的定义,对于扩展 Vehicle 的每个类型
T
Foo
是 Foo<* extends Vehicle>
的子类型.这意味着通配符在您只关心返回类型时非常有用,但在您想将类型的值传递给方法的情况下则不起作用.
Method arguments are contravariant in the subtype, and by the definition of the wildcard, for every type T
that extends Vehicle
Foo<T>
is a subtype of Foo<* extends Vehicle>
. The implication of this is that wildcards are great when you only care about the return type, but dont work in situations like this when you want to pass a value of the type to a method.
问题是用户可能会尝试调用
The problem is that a user might try to call
List<SpaceShip> l = ...
addCars(l);
如果要编译您的代码,l
将是包含 3 辆汽车的宇宙飞船列表.显然不好.
if your code were to compile, l
would then be a list of spaceships containing 3 cars. Clearly no good.
这篇关于Java 泛型通配符问题:List<?延伸A>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!