【问题标题】:Why is adding a subclass a of type in a collection is illegal?为什么在集合中添加类型为 a 的子类是非法的?
【发布时间】:2012-08-30 14:49:33
【问题描述】:

鉴于此代码 sn-p

    //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&lt;List&lt;Number&gt;&gt; 不是超级类型 List&lt;List&lt;Double&gt;&gt;?

【问题讨论】:

  • 您的意思是 num.add(d) 而不是 num.add(doub)?
  • 泛型类型必须准确,除非您允许? extends 子类型或? super 超类型。
  • 我编辑了代码。他的意思是num.add(d),否则这个问题就没意思了!

标签: java generics wildcard pecs


【解决方案1】:

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

【讨论】:

  • 你能给我一个关于我的例子的例子吗?
  • 我会这样做吗?列表 ?
  • @KyelJmD:这应该对你有帮助。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    就编译器关注List&lt;&gt; 部分而言,List&lt;Double&gt;List&lt;Number&gt; 没有任何关系。

    因此List&lt;List&lt;Double&gt;&gt; 不继承自List&lt;List&lt;Number&gt;&gt;,它们是Java 泛型系统的两种完全不同的类型。这不是构建类时的extends 关系。

    【讨论】:

      【解决方案4】:

      鉴于声明的类型,doub.add(d)num.add(doub) 暗示 add() 的行为不一致。如果doub.add(d) 有效,我不希望num.add(doub) 也有效。

      你是不是想测试一下

      num.add(d)
      

      而不是

      num.add(doub)
      

      ?

      【讨论】:

        猜你喜欢
        • 2012-02-13
        • 1970-01-01
        • 2011-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-06
        • 1970-01-01
        相关资源
        最近更新 更多