为什么在集合中添加类型的子类a是非法的?

时间:2012-08-30 14:49:33

标签: java generics wildcard pecs

给出此代码段

    //Creates a list of List numbers
    List<List<Number>> num = new ArrayList<List<Number>>();
    //Creates a list of List doubles
    List<List<Double>> doub = new ArrayList<List<Double>>();
    //List of doubles
    List<Double> d = new ArrayList<Double>();
    d.add(2.5);
    d.add(2.6);
    doub.add(d);

    num.add(d);//This code will not compile

为什么不允许num.add(doub)?不是List<List<Number>>超级类型的 List<List<Double>>

4 个答案:

答案 0 :(得分:6)

Generics inheritance与我们对继承的理解没什么不同。如果您想使用子类类型,则需要在泛型中使用extends(或)super定义边界(wildcards)。

enter image description here

答案 1 :(得分:1)

您正尝试将列表列表添加到带有列表的列表中。 (不是在编辑后我看到)

或者可能不那么令人困惑:

Your num list can only add List<Number>, you are trying to add a List<List<Double>>.

此外,使用泛型的继承不起作用,即使你确实添加了一个双精度列表,它也行不通。

如果你这样定义num:

    List<List<? extends Number>> num = new ArrayList<List<? extends Number>>();

然后你就可以做到这一点:

    num.add(d);

但不是:

    num.add(doub);

答案 2 :(得分:0)

List<Double>List<Number>没有任何关系,因为compilre关注List<>部分。

因此List<List<Double>>不会从List<List<Number>>继承它们是Java Generics系统的两种完全不同的类型。这与构建类时不是extends关系。

答案 3 :(得分:0)

鉴于声明的类型,doub.add(d)num.add(doub)意味着add()的行为不一致。如果doub.add(d)有效,我也不会指望num.add(doub)

您是否意味着要测试

num.add(d)

而不是

num.add(doub)