Java - 泛型
一、泛型概述
泛型:JDK1.5设计了泛型的概念,泛型即为“类型参数”,这个类型参数在声明它的类、接口或方法中,代表未知的通用的类型
泛型的优点:避免类型转换,通过编译提示异常来保证安全
泛型语法:
<类型>
- 一般形式为
,这里 可以看做类型形参, 等看做类型实参
- 一般形式为
泛型之后的Java数据类型
- Class
:Class类的实例表示正在运行的 Java 应用程序中的类和接口
- Class
- GenericArrayType:泛化的数组类型,即T[]
- ParameterizedType:参数化类型(例如:Comparator
,Comparator ) - TypeVariable:类型变量(例如:Comparator
中的T,Map<K,V>中的K,V) - WildcardType:通配符类型(例如:Comparator<?>)
二、泛型类与泛型接口
语法格式:
class 类名/接口名 <类型变量列表>
核心类库中的泛型类/接口
- 集合框架内的相关类和接口
- Comparator接口
- Comparable接口
自定义泛型类/接口
- 使用场景:
- 当某个类/接口的非静态变量的类型不确定,需要在创建对象或子类继承时才能确定
- 当某个(些)类/接口的非静态方法的形参类型不确定,需要在创建对象或子类继承时才能确定
- <类型变量列表>可以是一个或多个类型变量,一般都是使用单个的大写字母表示
泛型类/接口的使用:需要在创建泛型类的对象时指定类型变量对应的实际类型参数
- 实际类型参数必须是引用数据类型,不能是基本数据类型
- 子类/接口继承泛型父类/接口、或实现类实现泛型父接口时
- 父类/接口指定类型变量对应的实际类型参数,此时子类或实现类不再是泛型类
- 父类/接口指定类型变量(该类型变量可以和原来字母一样,也可以换一个字母),此时子类、子接口、实现类仍然是泛型类或泛型接口
- 泛型不存在多态现象,指定泛型实参时,必须左右两边一致
- <类型变量列表>中的类型变量不能用于类的静态成员
JDK1.7支持简写形式:Student stu1 = new Student<>();
三、泛型方法
语法格式:
【修饰符】 <类型变量列表> 返回值类型 方法名(【形参列表】)【throws 异常列表】{}
核心类库中的泛型方法
- java.util.Arrays数组工具类的大多数方法
自定义泛型方法
- 使用场景:
- 定义类、接口时没有使用<类型变量>,但是某个方法形参类型不确定
- 当某个静态方法的形参类型不确定时,静态方法可以单独定义<类型变量>
- <类型变量列表>:可以是一个或多个类型变量,一般都是使用单个的大写字母表示
泛型方法的使用:方法调用时,实参的类型确定泛型方法类型变量的具体类型
四、类型变量的上限
语法格式:
- 单个上限:
<类型变量 extends 上限>
- 多个上限:
<类型变量 extends 上限1 & 上限2>
(只能有一个类,且必须写在最左边)
- 单个上限:
如果在声明<类型变量>时没有指定任何上限,默认上限是java.lang.Object
五、泛型的擦除
- 泛型擦除:当使用参数化类型的类/接口或方法时,没有指定泛型,则自动按照最左边的第一个上限处理(如果没有指定上限,上限为Object)
1 | package com.atguigu.wildcard; |
六、类型通配符
使用场景:声明一个泛型类/接口的变量/形参,但仍然无法确定这个泛型类/接口的类型变量的具体类型
类型通配符的三种使用形式
<?>
:代表任意类型<? extends 上限>
:代表<=上限的类型<? super 下限>
:代表>=下限的类型
1 | package com.atguigu.wildcard; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 妙妙屋!