【问题标题】:Why is it not possible to call List<Number> not with List<Integer> even if Integer extends Number?为什么即使 Integer 扩展 Number 也不能用 List<Integer> 调用 List<Number>?
【发布时间】:2013-08-29 14:39:31
【问题描述】:

我想知道为什么不能用 List&lt;Integer 调用 List&lt;Number&gt; 甚至 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);
}
}

要解决它,我可以使用 List&lt;?&gt; 或 List&lt;? extends Number&gt;... 所以我不需要解决方案,我想知道确切的原因。

我能想到的唯一解决方案 List 是将 Number 绑定为一种新的数据结构类型。

【问题讨论】:

标签: java generics


【解决方案1】:

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

public void myMethod(List<Number> list) {
    list.add(new Double(5.5));
}

如果允许您使用 List&lt;Integer&gt; 的实例调用 myMethod,这将导致在调用 add 时发生类型冲突。

【讨论】:

    【解决方案2】:

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

    考虑类 Vehicle、Bike 和 Car。

    如果你做

    public void addVehicle(List<Vehicle> vehicles){
        vehicles.add(new Car());
    }
    
    • 这是可能的,因为Car 的类型为Vehicle,您可以添加一个 Car 转换为 Vehicle,因为它通过了 IS-A 测试。
    • 但是如果允许将List&lt;Bike&gt; 传递给addVehicle(List&lt;Vehicle&gt; vehicles) 会怎样?

    您会在自行车列表中添加Car。这是完全错误的。所以泛型不允许这样做。

    阅读Polymorphism with generics

    【讨论】:

      猜你喜欢
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 1970-01-01
      相关资源
      最近更新 更多