问题

  • 存放多个(不同类型)对象,容易出现转型错误ClassCastException

解决办法

  • 引入泛型:存放多个对象(限定一种类型),不需要转型,没有转型错误

简介

  • 泛型:jdk1.5推出的特性
  • 编写的代码可以被很多不同类型的对象所重用
  • 泛型类:ArrayList,HashSet,HashMap等
  • 泛型方法:Collections.binarySearch等
  • 泛型接口:List,Iterator等
  • 泛型的本质:参数化类型,避免类型转化,代码可复用

自定义泛型

  • 泛型类
    具有泛型变量的类,在类名后用<T>代表引入类型,多个字母表示多个引入类型,如<T,U>等,引入类型可以修饰成员变量/局部变量/参数/返回值
  • 泛型方法
    具有泛型参数的方法,该方法可在普通类/泛型类中,在修饰符后,返回类型前
  • 泛型接口
    和泛型类相似,在类名后加,T用来指定方法返回值和参数,实现接口时,指定类型

泛型类型限定

  • 泛型限定
    约定T必须是Comparable的子类,extends固定,后面可以多个,以&拼接,如<T extends Comparable & Serializable>,extends限定可以有多个接口,但只能一个类,且类必须排第一位,逗号隔开参数,<T extends File & Cloneable,U extends Serializable>
  • 泛型继承原则
    Pair<S> 和Pair<T>没有任何关系,无论S和T之间是什么关系
    泛型类可以扩展或实现其他的类,如ArrayList实现List
  • 上限界定符,Pair<? extends S>
  • Pair能接收的参数类型是S自身或子类
  • 只能get/不能set,编译器只能保证出来的类型,但不保证放入的对象是什么类型
  • 多泛型参数 java java 多个泛型_泛型类

  • 下限界定符,Pair<? super S>
  • Pair能接收的类型参数,是S的自身或超类
  • 只能set/不能get,编译器保证放入的是S本身或超类,但不保证出来是什么具体类型
  • 多泛型参数 java java 多个泛型_Pair_02

  • 无限定类型通配符
    Pair<?>,无限定通配符,表示任意类型
  • 泛型PECS原则
    Producer Extends,Consumer Super
    要从泛型类型读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends,泛型类是生产者,往外输出东西)
    如果要向泛型类写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super,泛型类是消费者,往内增加东西)
    如果既想写入又想读出,那就不用通配符

泛型实现的本质和约束

  • jdk的版本是向后兼容的,即低版本的Class文件可以在高版本的jdk上运行,因此,jvm里面没有泛型对象,而是采用类型擦除技术,只有普通的类和方法
  • 类型擦除
    擦除泛型变量,替换为原始类型,无限定为Object,有限定则为第一个类型,擦除泛型变量后,为了保证类型的安全性,需要自动进行类型转换,虚拟机也会用合成桥方法来保持方法多态
  • 泛型的约束

java类型协变和逆变

  • 类型变化关系
    A、B是类型,f(.)表示类型转换,≤表示继承关系,如A≤B,表示A继承于B
  • java类型变化
    数组是协变的
    String是Object的子类,String[]是Object[]的子类
    java的原始泛型是不变的
    String是Object的子类,List和List