Java 泛型 PECS
2016-10-27 00:00
155 查看
最近在研究框架的源码,发现有好多代码中使用了很多泛型了的用法<? extends>和<? super>。以前看《Java编程思想》的时候也有所了解,但是具体不是很清楚,所以写了这篇博客分享一下。其实这写用法可以叫做Java泛型PECS法则。
如果它表示一个消费者就使用<? super T>。
下面举例说明:
1. 生产者:
有一个List<Producer> producerList, 如果我们只从这个producerList中读取数据,而不从中添加数据,那这个List就称为Producer,即生产者。
2.消费者:
如果我们只向一个List<Consumer> consumer中添加数据,则这样的List就被称为Consumer,即消费者。
定义numList:
<? 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)
一、什么是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)
相关文章推荐
- Java 泛型: 什么是PECS(Producer Extends, Consumer Super)
- [转]Java 泛型: 什么是PECS(Producer Extends, Consumer Super)
- Java 泛型: 什么是PECS(Producer Extends, Consumer Super)
- Java下的Framework编写(反射,泛型,元数据,CGLib,AOP,IOC)(1)--序
- J2SE:JAVA泛型
- [ZT]Anders Hejlsberg谈C#、Java和C++中的泛型
- Java下的Framework编写(反射,泛型,元数据,CGLib,代码动态生成,AOP,动态语言嵌入)(1)--序
- Anders Hejlsberg谈C#、Java和C++中的泛型
- Anders Hejlsberg谈C#、Java和C++中的泛型
- 泛型在Java中的用法。(摘自精通Jbuilder 2005)
- Java 5.0泛型编程之泛型类型
- “泛型Java”,一个美丽的hype
- 关于java1.5的泛型(general)的学习
- Java 5.0泛型编程之泛型类型(1)
- Anders Hejlsberg谈C#、Java和C++中的泛型
- [转]Anders Hejlsberg谈C#、Java和C++中的泛型
- 诊断 Java 代码:轻松掌握 Java 泛型
- 掌握 Java 泛型类型(四)
- (收藏)Anders Hejlsberg谈C#、Java和C++中的泛型
- java 泛型 学习。