泛型PECS的理解

首先说明本文不是解释或教学PECS的,如果还不懂的读者可以参考下文。
Java泛型中的PECS原则

在这里插入图片描述
本文针对上述两个下划线部分阐述自己的理解。

extends不能写入吗?

确切地说,并不是。就比如List的常用实现类ArrayList是允许存null的,当然这个是视不同数据结构规则不一样。
但除了null外,任何对象(包括Obeject)也不能写入,如图。
在这里插入图片描述

super不能读数据吗?

确切地说,也不是,因为get能返回一个Obejct一个,任何时候都可以用Object来接住,如图
在这里插入图片描述
但这是无意义的,因为你用Object类去接收,就代表了你无法调用任何子类相关的方法。

通过强制转型不是可以吗?

常见资料里见到的基本都是:
在这里插入图片描述
然后得出不能读取的结论,有些“聪明”的小伙伴可能就会这么想了:(此处以Apple为例)

既然下界数组可以写入Apple类及其子类,那我读出来的时候用Apple类或者他们的父类来接住不就行了吗?

然后实操了一手,果然“可以”
在这里插入图片描述
编译器都没报错,甚至有些“严谨”的盆友还打印了一下,看看运行会不会报错。
在这里插入图片描述
也没问题啊,然后开始怀疑人生,难道这个原则有问题?然后一番操作之后推论出:这个原则是建立在不进行强制转型的条件上,可是一查资料啥都没有。

好了,上面的又聪明又严谨的人就是笔者我了。

现在思考一个问题。
为什么不能写入,却又能读呢?
当然了,不是说不能写入,你可以写入Apple类跟它子类,但难道真的是让你自己写入数据再读吗?

回到本质来,这是一个泛型的数组,而数组,就比如ArrayList,是可以接收实现了Collection接口的数组作为构造参数的

public ArrayList(Collection<? extends E> c) {}

到此,真相就差不多浮出水面了
在这里插入图片描述
如图,我们创建一个Fruit的数组,并把它作为参数去构造我们的<? super Apple>泛型数组,显然,编译器还是没有报错(原因是泛型擦除,读者请自行了解),但一运行,错误就如期而至了。

在这里插入图片描述

Fruit cannot be cast to Apple

至此,强制转型出错了(终于!!!)。

所以不是自己脑洞大开推测的什么建立在没有强制转型的条件下巴拉巴拉的,而是就是不能读取(Object还是可以读取的,但上面说过了,无意义)。甚至根本不应该用强制转型,因为这会让问题到运行才发现

总结

PECS原则是正确的

尽管可以写入null,用Object读取。
但这些顶多就是“钻牛角尖”的借口,不过拓展一下知识点还是不错的。

本文完,有误欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值