我的 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。

相关推荐
IT枫斗者枫哥1 小时前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
代码方舟1 小时前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
独泪了无痕1 小时前
Hutool之RandomUtil:随机数生成的终极利器
java·后端
花开路口1 小时前
深入理解 Java/Kotlin 协变与逆变
java·kotlin
运行时异常1 小时前
【WMS 仓储系统集成 AI Agent 实战】第 7 讲:Vue3 前端工程化——Token 刷新锁、Markdown 渲染踩坑与权限体系
java
她的男孩1 小时前
开放接口限流从 20 改到 200 还是每分钟 20 次:拆完防重放+幂等+限流,我找到 5 个静默失效的坑
java·后端·架构
天天被压力1 小时前
【Python 量化取数指南 #13】Python 把行情落库:sqlite 一键存,回测随用随取
java·人工智能·python
天天被压力1 小时前
【Python 量化取数指南 #14】Python 清洗行情数据:复权停牌对齐,回测不翻车
java·人工智能·python
独泪了无痕1 小时前
开发利器Hutool之MapUtil的使用
java·后端