目录
- 概述
- 什么是泛型
- 分类
- 泛型类
- 泛型接口
- 泛型方法
- 泛型通配符
- 分类
- 泛型类型擦除
- 分类
- 无限制类型擦除
- 有限制类型擦除
- 问题
- 需求
- 第一种
- 第二种
概述
了解泛型有利于学习 jdk 、中间件的源码,提升代码抽象能力,封装通用性更强的组件。
什么是泛型
- 在定义类、接口和方法时,可以在声明时通过一定的格式指定其参数类型
- 使用时再指定具体的类型,从而使用类、接口和方法可以被多种类型的数据所实例化和调用
- 这种可以在编译时进行参数类型检查的技术被称为泛型,是
jdk 5
中引用的一个新特性 - 本质是
参数化类型
,给类型指定一个参数,在使用时再指定参数具体的值,那这个类型可以在使用时决定
- 优点
- 将运行时的错误,提前到编译时,这样可以在编译时将错误提示出来,避免了运行时出现错误
- 使用泛型可以提高代码的复用性,因为它可以支持多种类型的数据
- 减少了源代码中的强制类型转换、代码更加可读
分类
- 可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法
- 泛型字母通常类型参数都使用大写的单个字母
- T:任意类型 type
- E:集合中元素的类型 element
- K:key-value 形式 key
- V:key-value 形式 value
泛型类
- 泛型类
- 泛型类型必须是引用类型,即类类型 (不能使用基本数据类型)
- 在类名后添加一对尖括号,并在尖括号中填写类型参数
- 如果参数可以有多个,多个参数使用逗号分隔
public class 类名<泛型1,...>{
private 泛型类型 变量名
public 泛型类型 方法名(){};
public 返回值 方法名(泛型类型 t) {}
}
注意
- 泛型类创建的使用没有指定类型,则默认是object类型
- 泛型类型从逻辑上看是多个类型,实际都是相同类型
- java 可以创建对应的泛型对象和泛型数组引用,但不能直接创建泛型对象和泛型数组
- java有类型擦除,任何泛型类型在擦除之后就变成了 Object 类型
- 因此创建泛型对象就相当于创建了一个 Object 类型的对象
- 所以直接创建泛型对象和泛型数组的行为被编译器禁止
泛型接口
注意
- 泛型知识点
- 如果泛型类的子类也是泛型类,那父类和子类的类型要一致
- 如果子类泛型有多个,那需要包括父类的泛型类型
class Child <T,E,E> extends Parent<T> {
}
泛型接口 接口名称 <泛型类型1,...>{
}
泛型方法
泛型方法
- 调用方法的时候指定泛型的具体类型
- 格式如下
修饰符 <T,E,...> 返回值类型 方法名(){ }
- 修饰符和返回值中间有
<T,E,...> 才是泛型方法
泛型类里的普通返回值类型不是泛型方法
- 注意
- 泛型类的类型和泛型方法的类型是互相独立的,同名也不影响
- 声明了
泛型方法
在参数列表和方法体里面才可以用对应的泛型
- 使用了类泛型的成员方法,不能定义为静态方法;使用了泛型方法的才可以定义为静态方法
- 可变参数的泛型方法
泛型通配符
- java 泛型的通配符是用于解决泛型之间引用传递问题的特殊语法
// 表示类型参数可以是任何类型
public class CustomCollection<?>{}
// 表示类型参数必须是A或者是A的子类
public class CustomCollection<T extends A>{}
// 表示类型参数必须是A或者是A的超类型
public class CustomCollection<T supers A>{}
分类
- 通用类型通配符 <?> 如 List<?>
- 主要作用就是让泛型能够接受未知类型的数据
- 可以将 ? 看成所有泛型类型的父类,是一种真实的类型,类型通配符是实参,不是形参
- 固定上边界的通配符采用 <? extends E> 的形式
- 使用固定上边界的通配符的泛型,只能够接受指定类型及其子类类型的数据
- 采用<? extends E> 的形式,这里的E就是该泛型的上边界
- 注意:虽然使用 extends 关键字,却不仅限于继承了父类E的子类 ,也可以代指实现了接口的 E 的类
- 固定下边界的通配符,采用 <? super E> 的形式
- 使用固定下边界的通配符的泛型,只能够接受指定类及其父类类型的数据
- 采用<? super E> 的形式,这里的 E 就是该泛型的下边界
- 可以为一个泛型指定上边界或下边界,但是不能同时指定上下边界
泛型类型擦除
泛型是 jdk 1.5 后出现的,但泛型代码和常规版本代码可以兼容,主要原因是泛型信息是在代码编译阶段,代码编译完成后进入 jvm 运行前,相关的泛型类型信息会被删除,这个即 泛型类型擦除
作用范围:类泛型、接口泛型、方法 泛型
分类
无限制类型擦除
擦除后都是 Object,没指定类型则擦除后是 Object 最顶级父类
有限制类型擦除
问题
如何解决创建 泛型数组和获取全部数组
需求
创建一个类里面支持泛型数组和返回全部数组的方法
第一种
可以通过返回下的 Array.newInstance 创建泛型数组,自动生成指定的类型字节码即可,使用可以创建实际类型的数组
第二种
jdk源码 ArrayList中的实现