ArrayList 和Double
问题内容:
来自http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ103:
具有下限的通配符看起来像“?super Type”,代表所有类型的族,它们是Type的超类型,包括Type类型。类型称为下限。
所以为什么
ArrayList<? super Number> psupn1 = new ArrayList<Number>();
psupn1.add(new Double(2));
编译?
Double不是Number的超类型,而是Number的子类…
编辑1:
ArrayList<? super Number> pextn1 = new ArrayList<Number>();
psupn1.add(new Integer(2));
psupn1.add(new Double(2));
psupn1.add(new Float(2));
for(Number n : psupn1){ // [Invalid] Number should be change to
// Object even if I can only add subtype of Number??
}
问题答案:
您可以 _添加_一个Double
,因为无论类型参数E
是什么,它都可以保证是Number
或超类型…这意味着您可以肯定地从转换Double
为E
。您将无法执行以下操作:
Number x = psupn1.get(0);
虽然。
考虑一下,然后尝试创建在逻辑上将其破坏的列表。例如,您不能使用:
// Invalid
ArrayList<? super Number> psupn1 = new ArrayList<Integer>();
psupn1.add(new Double(2));
因为Integer
既不 是Number
父类型 也不 是父类型-它是子类。你可以写:
// Valid
ArrayList<? extends Number> psupn1 = new ArrayList<Integer>();
…因为那是相反的方式。那时您可以写:
Number x = psupn1.get(0);
因为列表中的任何元素都保证可以转换 为 Number
。它涉及 到 需要转换的方式-转换为泛型类型参数或 从中 进行转换。