在平时看源码的时候我们经常看到泛型,且经常会看到
extends
和
super
的使用,看过其他的文章里也有讲到上界通配符和下届通配符,总感觉讲的不够明白。这里备注一下,以免忘记。
-
extends
也成为上界通配符,就是指定上边界。即泛型中的类必须为当前类的子类或当前类。 -
super
也称为下届通配符,就是指定下边界。即泛型中的类必须为当前类或者其父类。
这两点不难理解,
extends
修饰的只能取,不能放,这是为什么呢?
先看一个列子:
public class Food {}
public class Fruit extends Food {}
public class Apple extends Fruit {}
public class Banana extends Fruit{}
public class GenericTest {
public void testExtends(List<? extends Fruit> list){
//报错,extends为上界通配符,只能取值,不能放.
//因为Fruit的子类不只有Apple还有Banana,这里不能确定具体的泛型到底是Apple还是Banana,所以放入任何一种类型都会报错
//list.add(new Apple());
//可以正常获取
Fruit fruit = list.get(1);
}
public void testSuper(List<? super Fruit> list){
//super为下界通配符,可以存放元素,但是也只能存放当前类或者子类的实例,以当前的例子来讲,
//无法确定Fruit的父类是否只有Food一个(Object是超级父类)
//因此放入Food的实例编译不通过
list.add(new Apple());
// list.add(new Food());
Object object = list.get(1);
}
}
复制代码
在
testExtends
方法中,因为泛型中用的是
extends
,在向
list
中存放元素的时候,我们并不能确定
List
中的元素的具体类型,即可能是
Apple
也可能是
Banana
。因此调用
add
方法时,不论传入
new Apple()
还是
new Banana()
,都会出现编译错误。
理解了
extends
之后,再看
super
就很容易理解了,即我们不能确定
testSuper
方法的参数中的泛型是
Fruit
的哪个父类,因此在调用
get
方法时只能返回
Object
类型。结合
extends
可见,在获取泛型元素时,使用
extends
获取到的是泛型中的上边界的类型(本例子中为Fruit),范围更小。
总结:
在使用泛型时,存取元素时用
super
,获取元素时,用
extends
。
转载于:https://juejin.im/post/5c653fe06fb9a049e3089d88