所以我一直在阅读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的教程也没有启发我。
答案 0 :(得分:7)
当您拥有? extends NaturalNumber
时,该参数可能是NaturalNumber
的某些其他子类,与EvenNumber
无关。例如,
Collection<? extends NaturalNumber> c = new ArrayList<OtherNaturalNumber>();
如果OtherNaturalNumber
延长NaturalNumber
,则有效。
因此,您无法在列表中添加EvenNumber
实例。你可以使用这个声明:
Collection<NaturalNumber> c = new ArrayList<>();
允许您添加任何NaturalNumber
个实例(包括EvenNumber
)。
另一方面,你可能想要制作那些嵌套的类static
(或者根本不嵌套它们)。
答案 1 :(得分:1)
首先Collection<? extends NaturalNumber>
应为Collection<NaturalNumber>
。 EvenNumber
(或任何NaturalNumber
或[{1}}的子类型)的实例可以通过这种方式放入集合中。
基本上NaturalNumber
表示Collection<? extends NaturalNumber>
的类型参数类型扩展为Collection
。所以说NaturalNumber
,class OddNumber extends NaturalNumber
的类型参数的类型可能是Collection
,OddNumber
无法安全地转换为。{/ p>
然而,还有另一个编译器错误。要在静态上下文中使用,或EvenNumber
每个内部类main(String[])
和NaturalNumber
都需要在每个类声明上放置修饰符EvenNumber
。
答案 2 :(得分:0)
你的问题是你告诉编译器Collection
的元素类型可以是extends NaturalNumber
的任何类型,但是你试图插入一个对象进去。就编译器而言,c
是Collection<OddNumber>
,您刚刚添加了EvenNumber
!