- <? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”
- <? super T>:是指 “下界通配符(Lower Bounds Wildcards)”
上界通配符使得支持类似下面的转换:
List<Parent>
=> List<Base>
即模板类T的泛型
Plate<Apple>
=> Plate<Fruit>
——“装水果的盘子一定能装苹果”
适用于频繁往外面读取
副作用是无法插入数据
1 | class Plate<T>{ |
1 | Plate<? extends Fruit> p=new Plate<Apple>(new Apple()); |
原因是编译器只知道容器内是Fruit或者它的派生类,但具体是什么类型不知道。可能是Fruit?可能是Apple?也可能是Banana,RedApple,GreenApple?编译器在看到后面用Plate赋值以后,盘子里没有被标上有“苹果”。而是标上一个占位符:CAP#1,来表示捕获一个Fruit或Fruit的子类,具体是什么类不知道,代号CAP#1。然后无论是想往里插入Apple或者Meat或者Fruit编译器都不知道能不能和这个CAP#1匹配,所以就都不允许。
下界通配符不影响往里存,但往外取只能放在Object对象里
适用于频繁往里面插入
1 | Plate<? super Fruit> p=new Plate<Fruit>(new Fruit()); |
下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制。既然元素是Fruit的基类,那往里存粒度比Fruit小的都可以。但往外读取元素就费劲了,只有所有类的基类Object对象才能装下。但这样的话,元素的类型信息就全部丢失。