Java泛型中的extends和super理解

  • Post author:
  • Post category:java


在平时看源码的时候我们经常看到泛型,且经常会看到

extends



super

的使用,看过其他的文章里也有讲到上界通配符和下届通配符,总感觉讲的不够明白。这里备注一下,以免忘记。


  1. extends

    也成为上界通配符,就是指定上边界。即泛型中的类必须为当前类的子类或当前类。

  2. 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