<? extends T>与<? super T>的区别

<? extends T>:

<? extends T>是get优先,put受限,适用于提取元素为主的场景。

<? extends T>可以赋值给任何T以及T的子类的集合,上界为T,取出的类型带有泛型限制,向上转型为T,除了null以外,任何元素不得添加进<? extends T>集合内。

<? super T>:

<? super T>是put优先,get受限,适用于存放元素为主的场景。

<? super T>可以赋值给任何T以及T的父类集合,下界为T,取出的类型会泛型丢失,添加时只能添加T或T的子类。

例子:

public class AnimalCatGarfield {
    public static void main(String[] args) {
        // 第一段:声明三个依次继承的集合:Animal > Cat > Garfield
        List<Animal> animals = new ArrayList<>();
        List<Cat> cats = new ArrayList<>();
        List<Garfield> garfields = new ArrayList<>();
        animals.add(new Animal());
        cats.add(new Cat());
        garfields.add(new Garfield());

        // 第二段:测试赋值操作
        // 下行编译报错,只能赋值Cat或Cat的子类
        List<? extends Cat> extendsCatsFromAnimal = animals;
        List<? extends Cat> extendsCatsFromCat = cats;
        List<? extends Cat> extendsCatsFromGarfield = garfields;

        List<? super Cat> superCatsFromAnimal = animals;
        List<? super Cat> superCatsFromCat = cats;
        // 该行编译报错,只能赋值Cat或Cat的父类
        List<? super Cat> superCatsFromGarfield = garfields;

        // 第三段:测试add方法
        // <? extends T> 添加受限,除了add(null)其它都编译报错
        extendsCatsFromCat.add(new Animal());
        extendsCatsFromCat.add(new Cat());
        extendsCatsFromCat.add(new Garfield());
        extendsCatsFromCat.add(null);

        // 下行编译报错,只能添加Cat或Cat的子类
        superCatsFromCat.add(new Animal());
        superCatsFromCat.add(new Cat());
        superCatsFromCat.add(new Garfield());

        // 第四段:测试get方法
        Cat cat = extendsCatsFromCat.get(0);
        // 下行编译报错,取出的类型带有泛型限制,都向上转型为Cat
        Garfield garfield = extendsCatsFromGarfield.get(0);
        // 所有super的泛型都能取出数据,但是会泛型丢失,只能返回Object类型元素
        Object object = superCatsFromCat.get(0);
    }
}
class Animal{}
class Cat extends Animal{}
class Garfield extends Cat{}
发布了149 篇原创文章 · 获赞 100 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/u011212394/article/details/102617119