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

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

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

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

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

例子:

<? extends T>与<? super T>的区别_第1张图片

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

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

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

        // 第三段:测试add方法
        //  添加受限,除了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{}

 

你可能感兴趣的:(Java基础)