JAVA 泛型通配符super
超类型限定和子类型限定相反,可以给方法提供参数,但是不能使用返回值。? super Number这个类型限定为Number的所有超类。
语句1:List<? super Integer> 无法确定sList中存放的对象的具体类型,因此sList.get获取的值存在不确定性,子类对象的引用无法赋值给兄弟类的引用,父类对象的引用无法赋值给子类的引用,因此语句错误。
语句2:List<? super Integer> 无法确定sList中存放的对象的具体类型,因此sList.get获取的值存在不确定性,子类对象的引用无法赋值给兄弟类的引用,父类对象的引用无法赋值给子类的引用,因此语句错误。
语句3:子类对象的引用可以赋值给父类对象的引用,因此语句正确。
下界<? super T>不影响往里存,但往外取只能放在Object对象里
使用下界<? super T>会使从这里取东西的get( )方法部分失效,只能存放到Object对象里。set( )方法正常。
因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制。既然元素是Fruit的基类,那往里存粒度比Fruit小的都可以。但往外读取元素就费劲了,只有所有类的基类Object对象才能装下。但这样的话,元素的类型信息就全部丢失。
下界类型通配符get方法受限,但可以往列表中添加各种数据类型的对象。因此如果你想把对象写入一个数据结构里,使用 ? super 通配符。限定通配符总是包括自己。
PECS(Producer Extends Consumer Super)原则
即:如果需要返回T,它是生产者(Producer),要使用extends通配符;如果需要写入T,它是消费者(Consumer),要使用super通配符。
- 频繁往外读取内容的,适合用上界Extends。
- 经常往里插入的,适合用下界Super。
需要返回T的src是生产者,因此声明为List<? extends T>,需要写入T的dest是消费者,因此声明为List<? super T>。
使用类似<? super Integer>通配符作为方法参数时表示:
- 方法内部可以调用传入Integer引用的方法,例如:obj.setFirst(Integer n);
- 方法内部无法调用获取Integer引用的方法(Object除外),例如:Integer n = obj.getFirst();