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或超类型…这意味着您可以肯定地从转换DoubleE。您将无法执行以下操作:

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。它涉及 需要转换的方式-转换为泛型类型参数或 从中 进行转换。