泛型<? extends T> 和 <? super T> 的理解

看了几篇博客,发现写的不是很通俗易懂,所以自己撸一篇
如下是代码:
首先我们创建了两个类Fruit ,Orange 分别是父子的关系;

public class Generics {
    static class Fruit {
    }

    static class Orange extends Fruit  {
    }

    public static void main(String... args) throws Exception {
        List<? extends Fruit> list = new ArrayList<>();
        
        //第一处错误:无法安全添加不确定类型的元素
        list.add(new Orange());
        
        list.add(null);
        Fruit fruit = list.get(0);
        Orange orange = (Orange) list.get(0);
        

        //父类可以接收子类对象
        Fruit fruit1 = new Orange();
        //第三处错误:子类不可以接收父类对象
        Orange orange1 =  new Fruit();
        //父类可以强转子类对象
        Orange orange2 = (Orange) new Fruit();


        Orange orange3 = (Orange) list.get(0);

        List<? super Fruit> list1 = new ArrayList<>();
        list1.add(new Orange());
        
        //第二处错误:无法确定具体的返回类型
        Fruit fruit2 = list1.get(0);
        
        Orange orange4 = (Orange) list1.get(0);
    }
}

可以看到如上代码有三处编译错误

第一处错误:
首先是这个List<? extends Fruit>不能添加Orange对象;
虽然List<? extends Fruit> 表示是该List存放的是Fruit类对象或者Fruit子类对象;
但是编译器无法确定List所持有的类型,所以无法安全的向其中添加对象(比如String和Integer都是Object的子类,但是在确定泛型为String的List< String>中是不能放Integer的);
由于list里面的顶级类型是Fruit,所以可以安全取出Fruit类型 ;

//无法安全添加不确定类型的元素
list.add(new Orange());

第二处错误:
List<? super Fruit>无法取出Fruit类型对象;
由于List<? super Fruit>存放的至少是一个Fruit类型,因此可以安全的向其中添加Fruit及其子类型(比如List< Object >里面可以存放String也可以放Integer);
由于list里面的类型是从Fruit的父类,编译器无法确定返回的类型,所以直接取值时会报错(其实是无法确定接收类型,这里就要提到第三处报错,大家接着往下看);

//无法确定具体的返回类型
Fruit fruit2 = list1.get(0);

第三处错误:
这条就是用来解释为什么list1.get(0)不能用Fruit 类型接收,子类类型不可以直接接收父类对象(其实通过强转或者用Object也能接收)

//子类不可以接收父类对象
Orange orange1 =  new Fruit();

小结:
List<? extends Fruit> 可用于的返回类型限定,不能用于参数类型限定。
List<? super Fruit> 可用于参数类型限定,不能用于返回类型限定。
希望只取出,不插入,就使用? extends
希望只插入,不取出,就使用? super
希望,即能插入,又能取出,就不要用通配符

以上为个人理解,有不足的地方,还请各位指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值