【问题标题】:Generics:Issues in Adding SubClass Objects in a Collection泛型:在集合中添加子类对象的问题
【发布时间】:2013-08-21 02:38:50
【问题描述】:

所以我一直在阅读 Oracle 提供的泛型教程:http://docs.oracle.com/javase/tutorial/java/generics/

我已经尝试运行我自己的示例以确保我了解如何使用泛型。我有以下代码:

import java.util.*;

public class Generics {
    class NaturalNumber {
        private int i;

        public NaturalNumber(int i) { this.i = i; }
    }
    class EvenNumber extends NaturalNumber {
        public EvenNumber(int i) { 
            super(i);
        }
    }    
    public static void main(String[] args) {
        Collection<? extends NaturalNumber> c = new ArrayList<>();
        c.add(new EvenNumber(2)); //this line produces a compile time error     
    }
}

我的目标是能够将作为 NaturalNumber 子类型的任何对象添加到 Collection c。我不确定为什么这不起作用,阅读 Oracle 的教程也没有启发我。

【问题讨论】:

  • 请添加编译错误信息。 (我怀疑它实际上与泛型无关......)
  • 本教程的哪个特定部分让您感到困惑?如果我能找出您需要帮助的部分,我也许可以提供帮助。
  • link
  • 你是用 Java 7 还是旧版本编译这个?旧版本将无法使用。
  • @David Wallace:我使用的是 Java 6。但是下面的建议解决了我的问题。

标签: java generics


【解决方案1】:

当您有? extends NaturalNumber 时,该参数可能是NaturalNumber 的某个other 子类,与EvenNumber 没有任何关系。例如,

Collection<? extends NaturalNumber> c = new ArrayList<OtherNaturalNumber>();

如果OtherNaturalNumber 扩展NaturalNumber 则有效。

因此,您无法将EvenNumber 实例添加到列表中。你可以使用这个声明:

Collection<NaturalNumber> c = new ArrayList<>();

这将允许您添加任何NaturalNumber 实例(包括EvenNumber)。

另一方面,您可能打算创建这些嵌套类static(或者根本不嵌套它们)。

【讨论】:

  • 还要注意使用非静态内部类,导致错误non-static variable this cannot be referenced from a static context
  • @nickb 好点子,他很可能打算开设这些课程static
【解决方案2】:

第一个 Collection&lt;? extends NaturalNumber&gt; 应该只是 Collection&lt;NaturalNumber&gt;EvenNumber(或任何NaturalNumberNaturalNumber 的子类型)的实例可以通过这种方式放入集合中。

基本上Collection&lt;? extends NaturalNumber&gt; 表示Collection 的类型参数的类型扩展了NaturalNumber。所以说class OddNumber extends NaturalNumber,那么Collection的类型参数的类型可能是OddNumberEvenNumber不能安全地转换成。

但是还有另一个编译器错误。要在静态上下文或main(String[]) 中使用每个内部类NaturalNumberEvenNumber,需要在每个类声明上放置修饰符static

【讨论】:

    【解决方案3】:

    您的问题是您告诉编译器Collection 的元素类型可以是extends NaturalNumber 的任何类型,但随后您尝试向其中插入 一个对象。据编译器所知,cCollection&lt;OddNumber&gt;,而您刚刚添加了 EvenNumber

    【讨论】:

      猜你喜欢
      • 2012-09-02
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多