利用有限制通配符提升API灵活性(28)

别说谁变了你拦得住时间么 提交于 2019-12-03 20:51:52

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)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!