请解释一下extend和super泛型限定符,跳出上帝视角,一个小例子看懂二者区别!!

前言

很多人不理解上下限通配符的特征究竟为什么是它的特征,为什么它可以get不能add,为什么它不能get可以add,我明明这样这样那样那样就可以怎样怎样了,都是因为站在上帝视角看待问题。先看一下两者区别,不妨试试思考一下为什么?然后再看看实例,读完后有没有豁然开朗。

Extend和Super区别

上界<? extend Fruit> —> get()

extend上限通配符,用来限制类型的上限,初始化的时候只能传入本类和子类,可以get();add方法受阻。

下界<? super Apple> —> add()

super下限通配符,用来限制类型的下限,初始化的时候只能传入本类和父类,可以add();get方法受阻。

Extend和Super实例

考点:编译器可以支持向上转型,但不支持向下转型。
在这里插入图片描述

假如在某种开发环境下,你在编写一个方法,你通过方法让用户传递一个集合进来,你的遵循迪米特法则,不对用户传递来的集合做内部解析(实际上是用户可能用到的类型太多,你根本无法依次用instanceof判断集合中类型):

你尝试这样接收集合List<? extend Fruit>,于是,你知道用户可能传进来的集合为List<Fruit> list = new List<Fruit>()、List<Banana> list = new List<Banana>()、List<RedApple> list = new List<RedApple>()、List<DIYOrange> list = new List<DIYOrange>()等等,凡是继承水果的类,都有可能是集合中的类型,你不能完整预判到用户可能用到的所有子类型,你也不能复刻用户某个自定义的水果子类,所以你仅有的情报为Fruit。此刻你想完成一个add()的业务逻辑,你想add一个Fruit进去,发现根本不可能做到,因为你不能让用户定义的DIYOrange、RedApple…来指向你添加的Fruit。此刻你想完成一个get()的业务逻辑,你想get一个Fruit出来,发现完全行得通,只用Fruit就可以指向Fruit、Apple、Banana、RedApple、DIYOrange…。

你又尝试这样接收集合List<? super Apple>,于是,你知道用户可能传进来的集合为List<Fruit> list = new List<Fruit>()、List<Food> list = new List<Apple>()、List<Food> list = new List<Food>()、List<Object> list = new List<Object>()等等,凡是水果的超类,都有可能是集合中的类型,你不能完整预判到用户可能用到的所有超类,所以你仅有的情报为Apple。此刻你想完成一个add()的业务逻辑,你想add一个Apple进去,发现轻易就能做到,不论用户定义何种类型他们的类型Fruit、Food、Object都能指向你的Apple。此刻你想完成一个get()的业务逻辑,你想get一个Apple出来,发现受到了阻碍,你没办法让你仅有的Apple去指向Fruit、Food、Object类型对象…。

Extend和Super小Tips

①限定通配符总是包括自己。
②如果你既想存,又想取,那就别用通配符。
③不能同时声明泛型通配符上界和下界。

附加知识

T:作用于模板上,用于将数据类型进行参数化,不能用于实例化对象。
?:在实例化对象的时候,不确定泛型参数的具体类型时,可以使用通配符进行对象定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值