Java 泛型通配符问题:List<?延伸A> [英] Java Generics WildCard Question: List&lt;? extends A&gt;

查看:31
本文介绍了Java 泛型通配符问题:List<?延伸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 FooFoo<* 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屋!

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