例如,这段代码:
public void add(List<? super Number> list) {
list.add(1D); // можно
list.add(new Object()); // нельзя
}
这是为什么?因为这里 - <? super Number>- 它说:“任何类型都是Number”的超类。但它是相反的:“任何类型都是后继者Number”。怎么了?为什么反过来呢?
例如,这段代码:
public void add(List<? super Number> list) {
list.add(1D); // можно
list.add(new Object()); // нельзя
}
这是为什么?因为这里 - <? super Number>- 它说:“任何类型都是Number”的超类。但它是相反的:“任何类型都是后继者Number”。怎么了?为什么反过来呢?
是的,
<? super Number>它确实意味着“作为超类的任何类型Number”。加上我自己Number。出于这个原因,您可以传递给一个方法,例如,
List<Object>。由于此列表中元素的类型是“某类是”的超类
Number,因此您可以向列表中添加类型是“的子类”的元素Number。例如Integer:这是允许的,因为您可以将元素添加到列表,其类型是列表元素类型的子元素。与通常的情况一样
List<Number>:但是,您不能向列表中添加
new Object()内容,因为无法保证列表可以存储以下类型的元素Object:子元素?不仅可以“隐藏”Object,而且还可以“隐藏”,例如,它自己Number。在其他类 (? super X) 之间有中间类的情况Object下X- 也有任何中间类。由于列表元素的真实类型是未知的(
?),但任何类都有作为超类Object,那么从列表中获得的元素只能被视为 withObject。即使是他们自己刚刚放在那里的单元。在 case中,隐含了“
<? extends Number>作为子类的任何类型”。Number加上我自己Number。在这种情况下,您可以传递给该方法,例如,
List<integer>。由于元素类型是“某类是
Number”的子类,因此您不能向列表中添加任何内容(除了,也许null),因为不知道那里究竟可以存储什么。但是对于从列表中收到的元素,您可以使用
Number:因为列表中的任何元素,它们肯定来自子
Number类,这意味着它们可以作为Number.一切都很简单。
视图中
List'a的定义意味着该列表包含来自其中的某种类型的元素。它不一定在这里,继承层次中可能有一些中间类。wildcard<? super Number>NumberObject例如。
有课
A,B,C。A继承自B,B继而继承自C。如果我们写
List<? super A>,这意味着列表可以是List<A>,List<B>或List<C>。因此,如果它出现,List<B>那么放置该类型的元素C就会出错。编译器警告您不要出现此错误。