我的 Java 学习笔记 · 第 7 篇:泛型与通配符

这一篇整理《Java核心技术 卷1》第 8 章的泛型。泛型把类型信息交给编译器检查,减少集合里放错类型和取出后强制转换。

一、泛型先解决类型安全

没有泛型时,集合里常放 Object,取值后再转换;写成 ArrayList<String> 后,编译器能检查添加和读取的类型:

java 复制代码
ArrayList<String> names = new ArrayList<>();
names.add("Java");
String first = names.get(0);

二、泛型类和泛型方法

类型变量可以定义在类上,使用时再给出具体类型:

java 复制代码
class Pair<T> {
    private T first;
    private T second;
}

泛型方法在返回类型前声明自己的类型变量。下面的方法假设列表非空:

java 复制代码
public static <T> T first(List<T> values) {
    return values.get(0);
}

三、类型限定

<T extends Comparable<T>> 表示 T 必须能够与同类型对象比较。即使限定的是接口,关键字仍然是 extends;多个限定用 & 连接,例如 <T extends Number & Comparable<T>>。如果有类限定,它只能有一个,并且要写在接口限定前面。

四、通配符和读写方向

Pair<Manager> 不是 Pair<Employee> 的子类型,泛型通常不会因为类的继承关系自动变成协变类型。

  • ? extends Employee 是上界:可以把读取结果当作 Employee,但不能安全地放入某个具体的 Employee 值(null 除外)。
  • ? super Manager 是下界:可以放入 Manager 及其子类;读取时只保证得到 Object。

常用口诀是 PECS:Producer Extends,Consumer Super。作为数据提供者时优先考虑 extends,作为数据接收者时优先考虑 super。

五、类型擦除

编译后的泛型参数通常会擦除为原始类型或它的上界,所以 ArrayList<String> 和 ArrayList<Integer> 运行时属于同一个泛型类。由于运行时没有完整保留具体类型参数,new T()、new T[10] 和 instanceof Pair<String> 都不允许;可以用 instanceof Pair<?> 检查是否为某种 Pair。

一句话回顾

泛型让编译器先检查类型;遇到容器边界时,按读取或写入方向选择 extends 与 super。

相关推荐
猿究院_夏燊4 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog4 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿5 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河5 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
Jlzn88885 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
香吧香5 小时前
GRPC连接机制---长连接分析
java·网络与传输协议
我是人✓5 小时前
SpringBoot项目的五种创建方式
java·spring boot·后端
Wang's Blog6 小时前
Java 项目实战: 交友项目 - 阿里云 OSS 入门案例:从创建 Bucket 到上传拿到可访问 URL
java·阿里云·交友
裕晟资质规划7 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
念念清晰7 小时前
000-OpenJDK17 源码构建:MacOS环境(M芯片)
java·后端