原因是: Java编译期只知道容器里面存放的是Fruit和它的派生类,具体是什么类型不知道,可能是Fruit?可能是Apple?也可能是Banana,RedApple,GreenApple?编译器在后面看到Plate< Apple >赋值以后,盘子里面没有标记为“苹果”。只是标记了一个占位符“CAP#1”,来表示捕获一个Fruit或者Fruit的派生类,具体是什么类型不知道。所有调用代码无论往容器里面插入Apple或者Meat或者Fruit编译器都不知道能不能和这个“CAP#1”匹配,所以这些操作都不允许。
下界通配符的意思是容器中只能存放T及其T的基类类型的数据。我们还是以上面类层次的来看,<? super Fruit>覆盖下面的红色部分:
下界通配符<? super T>不影响往里面存储,但是读取出来的数据只能是Object类型。 原因是: 下界通配符规定了元素最小的粒度,必须是T及其基类,那么我往里面存储T及其派生类都是可以的,因为它都可以隐式的转化为T类型。但是往外读就不好控制了,里面存储的都是T及其基类,无法转型为任何一种类型,只有Object基类才能装下。
class Food{}
class Fruit extends Food {}
class Meat extends Food {}
class Apple extends Fruit {}
class Banana extends Fruit {}
class Pork extends Meat{}
class Beef extends Meat{}
class RedApple extends Apple {}
class GreenApple extends Apple {}