1、参数化类型是不可变的
- List<String> 不是List<Object>的子类,但是二者是有联系的
- 利用有限制的通配符类型处理类似情况
- List<? extends Object>(生产者)
- Collection<? super E>(消费者)
2、Object – 是所有类的根类,
- 任何类的对象都可以设置给该Object引用变量,可能需要类型强制转换
- 使用了泛型T、E等这些标识符后,在实际用之前类型就已经确定了,不需要再进行类型强制转换
- E – Element (在集合中使用,因为集合中存放的是元素)
- T – Type(Java 类)
- K – Key(键)
- V – Value(值)
- N – Number(数值类型)
- ? – 表示不确定的java类型(无限制通配符类型)
- <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
- <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object
4、当生成泛型类的字节码时,编译器用类型参数的擦除替换类型参数
- 无限制类型参数 (),它的擦除是 Object
- 上限类型参数(>),它的擦除是其上限的擦除
- 具有多个限制的类型参数,使用其最左限制的擦除
- 不要用通配符类型作为返回类型
5、PECS 原则
- 如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)
- 如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)
- 如果既要存又要取,那么就不要使用任何通配符
6、Comparable<? super T> 优于Comparable<T>

6.1、下述不能编译通过:

- 增加显式的类型参数,可以正确使用
![]()
6.2、List 使用了泛型,迭代器也要跟着变
![]()
7、无限制的类型参数(第一个)、无限制的通配符(第二个)
- 公共api 第二种更好一些,因为简单

8、下述代码,不能编译
- 不能将null 之外的任何值放入 List<?>

这种情况下,优先使用通配符,上述代码可以改为:

9、总结
- 使用通配符比较需要技巧,但是得api 灵活得多
- 注意PECS原则(producer Extends Consumer super)
来源:oschina
链接:https://my.oschina.net/u/3847203/blog/1831985