[TOC]
## 通配符和边界
![](https://img.kancloud.cn/f5/54/f554e61a785930a89cd057acd82c4e5d_499x658.png)
### T<? super B>
对于这个泛型,?代表容器里的元素类型,由于只规定了元素必须是B的超类,导致元素没有明确统一的“根”(除了Object这个必然的根),所以这个泛型你其实无法使用它,对吧,除了把元素强制转成Object。所以,对把参数写成这样形态的函数,你函数体内,只能对这个泛型做插入操作,而无法读
### T<? extends B>
由于指定了B为所有元素的“根”,你任何时候都可以安全的用B来使用容器里的元素,但是插入有问题,由于供奉B为祖先的子树有很多,不同子树并不兼容,由于实参可能来自于任何一颗子树,所以你的插入很可能破坏函数实参,所以,对这种写法的形参,禁止做插入操作,只做读取
### PECS
最后看一下什么是PECS(Producer Extends Consumer Super)原则,已经很好理解了:
* 频繁往外读取内容的,适合用上界Extends。
* 经常往里插入的,适合用下界Super
## 类型擦除
大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为**类型擦除**。
如在代码中定义`List<Object>`和`List<String>`等类型,在编译后都会变成`List`,JVM看到的只是`List`,而由泛型附加的类型信息对JVM是看不到的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法在运行时刻出现的类型转换异常的情况,类型擦除也是 Java 的泛型与 C++ 模板机制实现方式之间的重要区别。
### 优点
避免过多的创建类而造成的运行时的过度消耗。
## java补救
1、先检查再编译以及编译的对象和引用传递问题
### Json遇到泛型
利用`TypeReference`指定泛型中的类型, 就可以顺序反序列化成功,并且 集合中的对象也转换过来了。
## 推荐阅读
[java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一](https://blog.csdn.net/s10461/article/details/53941091)
[Java 泛型通配符?解惑](https://blog.csdn.net/baple/article/details/25056169)
[Java泛型类型擦除以及类型擦除带来的问题](https://www.cnblogs.com/wuqinglong/p/9456193.html)
- Java
- Object
- 内部类
- 异常
- 注解
- 反射
- 静态代理与动态代理
- 泛型
- 继承
- JVM
- ClassLoader
- String
- 数据结构
- Java集合类
- ArrayList
- LinkedList
- HashSet
- TreeSet
- HashMap
- TreeMap
- HashTable
- 并发集合类
- Collections
- CopyOnWriteArrayList
- ConcurrentHashMap
- Android集合类
- SparseArray
- ArrayMap
- 算法
- 排序
- 常用算法
- LeetCode
- 二叉树遍历
- 剑指
- 数据结构、算法和数据操作
- 高质量的代码
- 解决问题的思路
- 优化时间和空间效率
- 面试中的各项能力
- 算法心得
- 并发
- Thread
- 锁
- java内存模型
- CAS
- 原子类Atomic
- volatile
- synchronized
- Object.wait-notify
- Lock
- Lock之AQS
- Lock子类
- 锁小结
- 堵塞队列
- 生产者消费者模型
- 线程池