Java泛型
1. 泛型入门
1.1 泛型 Generic Programming
- 泛型类:ArrayList, HashSet, HashMap等
- 泛型方法:Collections.binarySearch,Arrays.sort等
- 泛型接口:List, Iterator等
1.2 泛型的本质:参数化类型,避免类型转换,代码可复用
2. 自定义泛型
2.1 泛型类
- 具有泛型变量的类
- 在类名后用
代表引入类型 - 多个字母表示多个引入类型,如<T,U>等
- 引入类型可以修饰成员变量/局部变量/参数/返回值
- 没有专门的template关键字
2.2 泛型方法
- 具有泛型参数的方法
- 该方法可以在普通类/泛型类中
在修饰符后,返回类型前
public class ArrayUtil {
public static <T> T getMiddle(T... a) {}
}
String s = ArrayUtil.<String>getMiddle("abc", "def");
2.3 泛型接口
- 和泛型类相似,在类名后加
- T用来指定方法返回值和参数
- T也可以再是一个泛型类
- 实现接口时,指定类型
2.4 总结
- 泛型类:整个类都被泛化,包括变量和方法
- 泛型方法:方法都被泛化,包括返回值和参数
- 泛型接口:泛化子类方法
3. 泛型类型限定
3.1 泛型限定
约定T必须是Comparable的子类 - extends固定,后面可以多个,以&拼接,可以有多个接口,但只能一个类,且类必须排第一位
- 逗号分隔参数
3.2 泛型类之间的继承
Pair<S>
和Pair<T>
没有任何关系,无论S和T之间是什么关系- 泛型类可以扩展或实现其他的类,如
ArrayList<T>
实现List<T>
3.3 界定符
-
Pair<? extends S>
Pair能接收的参数类型,是S自身或子类
只能get,不能set,只生产,不消费,编译器只能保证出来的类型,但不能保证放入的对象是声明类型 -
Pair<? super S>
Pair能接收的参数类型,是S自身或超类
只能set,不能get,只消费,不生产,编译器保证放入的是S自身或超类,但不能保证出来的是什么具体类型 -
PECS原则,Producer Extends, Consumer Super
3.4 无限定符的泛型
Pair<T>
,原始类型Pair<?>
,无限定通配符,表示任意类型,获取元素只能赋值给Object,无法放入任何对象,甚至是Object
4. 泛型的本质
4.1 类型擦除
- 虚拟机中没有泛型,只有普通类和方法
- 在编译阶段,泛型参数被擦除为第一个限定类型,如无限定类型,擦除为Object
- 重载泛型方法翻译(自动桥方法)保持方法多态
- 静态变量不支持泛型。
5. Java类型协变和逆变
5.1 定义
5.2 详情
-
Java数组是协变的
String是Object子类,String[]是Object[]的子类 -
Java的(原始)泛型是不变的
String是Object子类,List和List
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现