Java 泛型 PECS

最近在研究框架的源码,发现有好多代码中使用了很多泛型了的用法<? extends>和<? super>。以前看《Java编程思想》的时候也有所了解,但是具体不是很清楚,所以写了这篇博客分享一下。其实这写用法可以叫做Java泛型PECS法则。

一、什么是PECS:

  • PECS指“Producer Extends Consumer Super”如果参数化类型表示一个生产者就使用<? extends T>, 如果它表示一个消费者就使用<? super T>。

下面举例说明:

1. 生产者:

有一个List<Producer> producerList, 如果我们只从这个producerList中读取数据,而不从中添加数据,那这个List就称为Producer,即生产者。

2.消费者:

如果我们只向一个List<Consumer> consumer中添加数据,则这样的List就被称为Consumer,即消费者。

二、PECS的用法:

1.生产者的用法:

定义numList:

List<? extends Number> numList = new ArrayList<Number>(); 

<? extends Number>表示最高父类是Number类型,Integer, Double都属于Number的子类,所以在实例化List<? extends Number>这样的List时,可以传入任意Number类型的子类以及它自己,进行实例化。 1. <? extends Number>的最高父类是Number类型。所以从List<? extends Number>中拿出的数据可以保证是Number类型。 2. 假设List<? extends Number>中可以放Number、Double、Interger三种类型,当我们从List中取出数据时是不能确定具体是哪一种类型。所以List<? extends Number>是不能做添加操作的,Java是不允许这样的操作的。 ###### 2.消费者用法: 定义numList ``` List<? super Integer> intList = new ArrayList<Integer>(); ``` <? super Integer>表示最小子类是Integer,super代表了?可以是任意一种Integer的父类类型。所以可以向其添加任意Integer父类类型。但是Java是拒绝读取操作的。 ###### 3.总结: 1) 参数写成:T<? super B>,对于这个泛型,?代表容器里的元素类型,由于只规定了元素必须是B的超类,导致元素没有明确统一的“根”(除了Object),所以这个泛型你其实无法使用它(除了把元素强制转成Object)。所以只能插入操作,而无法读 2) 参数写成: T<? extends B>,由于指定了所有元素的“根”是B,你任何时候都可以安全的用B来使用容器里的元素,但是插入有问题,由于以B为祖先的子树有很多,不同子树不兼容,所以禁止做插入操作,只做读取 [参考1](http://dz.sdut.edu.cn/blog/subaochen/2017/01/generics-pecs/) [参考2](http://www.importnew.com/17006.html) [参考3](http://www.cnblogs.com/lucky_dai/p/5485421.html) [参考4](http://www.ciaoshen.com/2016/08/21/superExtends/) [参考5](http://leekai.me/java-extends-super//) [参考6](https://www.zhihu.com/question/20400700/answer/117464182)

转载于:https://my.oschina.net/famiover/blog/776635

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值