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

相关推荐
学长毕设1 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
SL_staff2 小时前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
这个昵称不容易2 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
装不满的克莱因瓶3 小时前
【SpringAI Alibaba】ReactAgent记忆管理MessageTrimmingHook与MessageDeletionHook
java·人工智能·ai·ai编程·springai·springaialibaba
文丑颜不良啊3 小时前
LeetCode2241~2260题目解析
java·leetcode
文丑颜不良啊3 小时前
LeetCode2321~2340题目解析
java·leetcode
驭渊的小故事4 小时前
Spring AOP 核心概念与通知类型详解
java·后端·spring
vipxieliang4 小时前
ValidX vs 手写验证代码:开发效率对比实测
java·spring boot·后端
vipxieliang4 小时前
虚拟线程与 GraalVM:Spring Boot 3.x 云原生性能跃迁
java·spring boot·后端
Rain的Java大神之路4 小时前
面试官最烦的答案:“我用 Redis + Token”!接口幂等 8 种方案 + 四层防御,把重复扣款工单干到 0
java·后端·面试