🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[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)