extends T> 和 super T> 是Java泛型中的“通配符(Wildcards)” 和 “边界(Bounds)”
extends T> 是指 “上界通配符”
super T> 是指 “下界通配符”
1、
public class Vehicle {
Auto4SStores as = new Auto4SStores();
}
class AutoS4Stores{
private T item;
public T get(){
return item;
}
public void set(T item){
this.item = item;
}
}
class Car extends Vehicle{}
class Audi extends Car{}
class Toyota extends Car{}
class Lexus extends Car{};
class Avalon extends Toyota{}
如上图,Audi是一种车(Car),但是4S店不一定是卖Audi的4S店,有可能是丰田(Toyota)的,等等,
所以Auto4SStores
public class Vehicle {
Auto4SStores extends Car> as = new Auto4SStores();
}
于是,上界通配符 extends T>的作用就体现出来了,
为什么叫上界通配符呢,可以理解为 ?继承(extends)自T或者T的派生类。Car类是所有泛型的上界。
而下界通配符 super T>
public class Vehicle {
Auto4SStores super Car> as = new Auto4SStores();
}
Car是三角区域的下边界,这里可以理解为 ?超类(super)Car,意思就是?是Car的超类,Car是泛型的最下边界
2、上界通配符 extends T>不能往里存,只能往外取
(1). extends Car>会使往盘子里放东西的set( )方法失效,但取东西get( )方法还有效
(2).取出来的东西只能存放在Car或它的基类里面,向上造型。
编译器只知道容器内是Car或者它的派生类,但具体是什么类型不知道,因此取出来的时候要向上造型为基类。
可能是Car,可能是Audi,也可能是Toyota或者子品牌凯美瑞,奥迪A4等等,编译器在看到后面用AutoStores
然后无论想进货一辆奥迪A4还是丰田汉兰达或者雷克萨斯ES编译器都不知道能不能和这个capture#1匹配,所以就都不允许。
下界通配符 super T>可能往里存,但往外取数据只能放到基类Object里面
因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制
既然元素是Car的基类,那往里存粒度比Car小的都可以。
但往外读取元素就费劲了,只有所有类的基类Object对象才能装下。但这样的话,元素的类型信息就全部丢失。
3、 PECS原则
Producer extends: 生产者确定上界 ,用extends
Consumer super: 消费者确定下界,用super
什么意思呢?
如果AutoStores代表一个生产者,那么泛型就可以用 extends T>表示,生产者生产的数据是供我们读取消费的
如果AutoStores代表一个消费者,那么泛型就可以用 super T>表示,因为我们需要往里面存数据供AutoStores去消费