经常看见框架很多这样的泛型写法<? extends T>,后来终于看了相关资料才明白。
<? extends T>是指“上界通配符”,<? super T>是指下界通配符。
比较有趣,而且有点烧脑,归根结底,还是一个上下转型的问题。
举例:有3个类,animal(动物),cat(猫),dog(狗)。猫和狗都继承动物类
<? extends T>: 如果以下赋值合法: //编译器会报错,new
ArrayList
需要指定类型
List<?
extends
Animal> f = new
ArrayList<?
extends
Animal>();
那么,能存放什么类型呢,有可能是猫,也可能是狗。
唯一可确认的就是读取出来,是一个动物或者它的子类型。
引申出---可以读取动物的任意子类
<? super T> 可以正常存入,
List<? super Animal> b = new ArrayList<>();
b.add(new Cat());
b.add(new Dog());
for (Object o : b) {
System.out.println(o);
}
但是获取的时候,只能是对象,因为可能是猫类,也可能是狗类。
引申出---可以存入动物的任意子类
所以,搭配使用,也就是
PECS(Producer Extends Consumer Super)原则,已经很好理解了:
- 频繁往外读取内容的,适合用上界Extends。
- 经常往里插入的,适合用下界Super。