泛型中extends和super的区别

首先来说:< ? extends T > 叫 上界通配符
< ? super T >叫 下界通配符
1. 下面用代码来说明上界通配符的一些特点

public class Fruit {

}
public class Apple extends Fruit {

}
public class Banana extends Fruit{

}

public class Plate<T> {

    private T item;

    public Plate(T item) {
        super();
        this.item = item;
    }

    public T getItem() {
        return item;
    }

    public void setItem(T item) {
        this.item = item;
    }

}
//下面为测试代码
Plate<? extends Fruit> plate = new Plate<Apple>(new Apple());

        Object item3 = plate.getItem();
        Fruit item = plate.getItem();
        Apple item2 = plate.getItem();//error

        plate.setItem(new Apple());//error
        plate.setItem(new Banana());//error

1). plate< ? extends Fruit > 编译器只知道容器内是存放的Fruit或者它的子类,但是并不知道是apple还是banana,只能知道上限是Fruit。
所以Apple item2 = plate.getItem();//error
2).原因是编译器只知道容器内是Fruit或者它的派生类,但具体是什么类型不知道。可能是Fruit?可能是Apple?也可能是Banana,编译器在看到后面用Plate赋值以后,盘子里没有被标上有“苹果”。而是标上一个占位符:CAP#1,来表示捕获一个Fruit或Fruit的子类,具体是什么类不知道,代号CAP#1。然后无论是想往里插入Apple或者Banana或者Fruit编译器都不知道能不能和这个CAP#1匹配,所以就都不允许。
所以:plate.setItem(new Apple());//error
plate.setItem(new Banana());//error

2 说明下界通配符的特点

Plate<? super Fruit> plate2 = new Plate<Fruit>(new Fruit());
        //取数据
        Object object = plate2.getItem();
        Fruit fruit = plate2.getItem();//error
        //存数据
        plate2.setItem(new Apple());
        plate2.setItem(new Banana());
        plate2.setItem(new Fruit());

因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制.元素的下界为Fruit,那么存数据的时候,可以存Fruit的子类。但是注意:取数据时只有Object才能装下,这样做会使数据类型的信息丢失。

3.PECS(product extends customer super)

            经常取数据时 用<? extends T>上界通配符
            经常存数据时 用<? super T>下界通配符

猜你喜欢

转载自blog.csdn.net/qdh186/article/details/79748548
今日推荐