Java泛型WildCard问题:列表&lt ;?延伸A> [英] Java Generics WildCard Question: List<? extends A>

查看:143
本文介绍了Java泛型WildCard问题:列表&lt ;?延伸A>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class车辆(
$ b $)我们有这些类:车辆,汽车和飞船: b void rideVehicle(Vehicle v){
System.out.println(我骑车!);
}

}

class Car extend Vehicle {
void rideVehicle(Vehicle c){
System.out.println(I正在骑车!);
}
}


class SpaceShip extend Vehicle {
void rideVehicle(Vehicle c){
System.out.println(I我骑着太空船!);
}

}

我写这个方法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的超类型。编辑:我得到的错误(编译时):方法添加(捕获)($) #2-of?extends Vehicle)不适用于参数(Car)。

解决方案

方法参数是在子类型中是不变的,并且通过通配符的定义,对于每个类型 T ,它们扩展车辆 Foo< T> Foo< * extends Vehicle> 的子类型。这意味着当你只关心返回类型时,通配符是很好的,但是当你想要将一个类型的值传递给一个方法时,在这种情况下不工作。



问题是用户可能试图呼叫

  List< SpaceShip> l = ... 
addCars(l);

如果您的代码要编译, l 那么将是一个包含3辆汽车的太空船列表。显然不好。


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!");
    }

}

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());

    }

Why do I get a compile time error?? I understand that List is a supertype of List for any X that extends Vehicle. right?

Thanks

Edit: 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).

解决方案

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);

if your code were to compile, l would then be a list of spaceships containing 3 cars. Clearly no good.

这篇关于Java泛型WildCard问题:列表&lt ;?延伸A&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆