为什么即使Integer扩展Number,也无法使用List <Integer>调用List <Number>?

Fen*_*rix 5 java generics

我想知道为什么List<Number>不能用List<Integer> 来调用它甚至整数是抽象类Number的扩展类?有一个逻辑错误,因为我可以使用参数Number和Integer调用Method.

public class Que
{

public void enterNumbers(List<Number> nummern)
{
    for (Number number : nummern)
    {
        System.out.println(number + "\n");
    }
}

public void enterNum(Number num)
{
    System.out.println("This is a number " + num);
}

public static void main(String[] args)
{
    Que que = new Que();

    Integer myInteger = new Integer(7);
    // possible (of course!)
    que.enterNum(myInteger);

    List<Integer> num = new ArrayList<Integer>();
    num.add(4);
    num.add(45);
    Integer inte = new Integer(333);

    num.add(inte);
    // not possible ! 
    que.enterNumbers(num);
}
}
Run Code Online (Sandbox Code Playgroud)

要解决它,我可以使用List<?>List<? extends Number>...所以我不需要解决方案,我想知道确切的原因.

我能想到的唯一解决方案是使用Number作为新的数据结构类型绑定.

Tho*_*mas 11

因为你可以如添加不同的子类的实例NumberList<Number>,例如,类型的对象Double,但显然你不应该被允许将它们添加到List<Integer>:

public void myMethod(List<Number> list) {
    list.add(new Double(5.5));
}
Run Code Online (Sandbox Code Playgroud)

如果允许您调用myMethod此实例,List<Integer>则会在add调用时导致类型冲突.


Pra*_*kar 8

泛型不像数组那样是共变的.由于类型擦除,这是不允许的.

考虑课程Vehicle,BikeCar.

如果你做

public void addVehicle(List<Vehicle> vehicles){
    vehicles.add(new Car());
}
Run Code Online (Sandbox Code Playgroud)
  • 这是可能的,因为一个Car是类型的Vehicle,你可以添加 CarVehicle,因为它通过IS-A测试.
  • 但是,如果它被允许传递List<Bike>addVehicle(List<Vehicle> vehicles)

你会Car在自行车列表中添加一个.这是完全错误的.因此泛型不允许这样做.

阅读有关泛型的多态性