List<? super Integer> lowerBounded = new ArrayList<Number>();
lowerBounded.add(0);
这里我们有一个引用,它允许一个整数列表或一个整数超类型。ArrayList of Numbers符合该定义,因此我们可以将其分配给该引用。然后我们可以向这个列表中添加一个Integer,这也很好,因为一个Numbers列表可以包含一个Integer(因为Integer是一个Number)。 这可能令人惊讶,但您不能将任何不可分配给Integer的内容添加到这个列表中,原因与我上面解释的下界泛型相同。
List<? super Integer> lowerBounded = new ArrayList<Number>();
lowerBounded.add(1.0); // compile-time error
List<? extends Number> L = new ArrayList<>();
L.add(new Integer(3)); //ERROR
L.add(new Double(3.3)); // ERROR
我相信**'L'是一个引用变量,可以指向ArrayList of Numbers或Number的子类(Integer,double等...)。 在某个时间点,如果'L'引用了Integer的ArrayList,这意味着向列表中添加Double值是很奇怪的,为什么因为'L'只是指向Integer的ArrayList的引用变量**,而你不能添加任何Integer以外的东西。 所以如果**'L'指向整数列表,那么我可以向它添加整数。你不能,因为这里**'L'是Number的上界,编译器不确定它是否指向整数列表,数字,double或Number的其他子类,所以它说,我不会向列表添加任何东西,即使****L指向整数数组列表,你试图添加一个像3这样的整数。 在上面的情况下,最好不要添加一个整数,因为在某个时间点,L可以指向double的列表,可怜的我试图添加除了double之外的东西......(想象一下你把List<?extends Number> L as method parameter or something and some one passes list of Integer one time,float the next day).请纠正我,如果我错了.. seri正确的varen!
7条答案
按热度按时间ewm0tg9j1#
List<? extends Number>
并不意味着“一个可以保存Number
的子类的所有对象的列表”,它意味着“一个参数化到一个扩展Number
的具体类的列表”。这不是你定义的列表本身的内容,而是分配给变量的实际列表对象的参数化类型(男孩,这比理解更难解释:)因此,您可以执行以下操作:
如果你想要一个能够容纳Number类或其子类的任何对象的列表,只需这样做:
(The插入的值的装箱是不必要的,但为了清楚起见。)
vkc1a9a22#
上界和无界通配符集合是不可变的。
例如,您不能执行以下操作:
这无法编译,因为java在编译时不知道List
List<? extends Number>
是什么类型。所以上面的例子,在编译时,
myList
可以是List<Double>
或List<Integer>
或Number
的任何子类的List
。由于不能将Double
添加到List<Integer>
,反之亦然,因此编译失败。pu82cl6c3#
上限泛型的问题是编译器不知道将要使用的确切类型,例如:
upperBounded
可以是整数列表,也可以是双精度数列表或Number的任何其他后代。现在想象一下,如果Java允许我们将Number的任何子类添加到该List中,会发生什么。好消息是Java阻止我们这样做,因为这会引入很多bug。
这同样适用于未绑定的泛型类型。
那么下界泛型呢?
这是非常好的,因为我们可以安全地假设我们可以将Integers添加到Integer超类的任何List中,并且这不会导致不一致,例如:
这里我们有一个引用,它允许一个整数列表或一个整数超类型。ArrayList of Numbers符合该定义,因此我们可以将其分配给该引用。然后我们可以向这个列表中添加一个Integer,这也很好,因为一个Numbers列表可以包含一个Integer(因为Integer是一个Number)。
这可能令人惊讶,但您不能将任何不可分配给Integer的内容添加到这个列表中,原因与我上面解释的下界泛型相同。
由于编译器不知道将使用哪个确切类型的List,因此它不允许我们添加任何可能破坏泛型给出的承诺的内容。
希望能帮上忙。
jqjz2hbq4#
因为
List<? extends Number>
意味着你的变量l
持有一个List
类型的值,其中具体(但未知!)扩展Number
的类型参数。您只能添加
null
,因为l
可以容纳List<MyClass>
,例如,其中MyClass
是扩展Number
的类,但Integer
和Double
值都不能转换为MyClass
。cclgggtu5#
我将添加另一种方法来将
Number
的子类型添加到此列表中。即这是允许的,因为列表被参数化为
Number
类的任何 * 未知超类型 *。因此,编译器允许已知的Number
子类型。即Integer
和Double
类型s2j5cfk06#
是,以防
这只是一个参考,可能是实际的对象会
所以你不应该被允许在Integer的列表中添加新的Double(5.0)。
ecfdbz9o7#
那么为什么我不能在上限泛型中添加元素呢?.
我相信**'L'是一个引用变量,可以指向ArrayList of Numbers或Number的子类(Integer,double等...)。
在某个时间点,如果'L'引用了Integer的ArrayList,这意味着向列表中添加Double值是很奇怪的,为什么因为'L'只是指向Integer的ArrayList的引用变量**,而你不能添加任何Integer以外的东西。
所以如果**'L'指向整数列表,那么我可以向它添加整数。你不能,因为这里**'L'是Number的上界,编译器不确定它是否指向整数列表,数字,double或Number的其他子类,所以它说,我不会向列表添加任何东西,即使****L指向整数数组列表,你试图添加一个像3这样的整数。
在上面的情况下,最好不要添加一个整数,因为在某个时间点,L可以指向double的列表,可怜的我试图添加除了double之外的东西......(想象一下你把List<?extends Number> L as method parameter or something and some one passes list of Integer one time,float the next day).请纠正我,如果我错了.. seri正确的varen!