Java 泛型

一、泛型的本质

1. 泛型要解决的根本问题

在没有泛型的时代,Java 集合只能以 Object 为通用载体:

List list = new ArrayList();list.add("hello");Integer i = (Integer) list.get(0); // 运行时异常

问题的本质是:

类型信息丢失 + 类型检查延后

错误只能在运行时暴露,而不是在编译期被发现。


2. 泛型的核心思想

泛型的本质:类型参数化(Parameterized Type)

泛型不是一种新功能,而是对类型系统的扩展:


3. 泛型带来的核心价值

泛型的价值可以归纳为三个维度:

维度本质
类型安全将运行时错误提前到编译期
表达能力明确数据结构中的类型意图
复用能力让同一套代码服务于多种类型

二、Java 泛型的核心模型

Java 泛型可以抽象为两个基本要素:

泛型 = 类型参数化 + 类型约束

泛型知识结构总览

泛型│├── 类型参数化│   ├── 泛型类│   ├── 泛型接口│   └── 泛型方法│├── 类型约束│   ├── 上界约束 extends│   ├── 下界约束 super│   └── 通配符 ?│├── 使用原则│   └── PESC 原则│└── 实现机制    └── 泛型擦除

三、类型参数化的三种形态

1. 泛型类

泛型类的本质:

把“类的类型信息”参数化

class Box<T> {    private T value;    public Box(T value) {        this.value = value;    }    public T get() {        return value;    }}

在这个结构中:


2. 泛型方法

泛型方法的本质:

把“方法的类型信息”参数化

public static <T> T identity(T obj) {    return obj;}

这里:


3. 泛型接口

与泛型类类似,接口也可以参数化:

interface Converter<F, T> {    T convert(F from);}

小结

这三种形态本质一致:

形态抽象层级
泛型类对数据结构参数化
泛型接口对行为参数化
泛型方法对单个逻辑参数化

四、类型约束:对泛型的边界控制

单纯的类型参数化过于自由,因此需要约束。


1. 上界约束(extends)

<T extends Comparable>

含义:

T 必须是 Comparable 的子类


可以指定多个接口:

<T extends Comparable & Serializable>

2. 通配符

通配符本质是:

对“泛型类型参数”的一种灵活表达


上界通配符

<? extends T>

语义:

接受 T 或 T 的子类型


下界通配符

<? super T>

语义:

接受 T 或 T 的父类型


无界通配符

<?>

语义:

不关心具体类型


五、PESC 原则:泛型使用的工程哲学

1. 原则本身

Producer Extends Consumer Super


2. 原理本质

这个原则并不是一个“经验口诀”,而是类型系统约束的必然结果。


上界通配符:协变视角(适合读)

List<? extends Fruit> basket;

特点:

本质原因:

编译器无法确定具体子类型


下界通配符:逆变视角(适合写)

List<? super Apple> basket;

特点:

本质原因:

只能保证是 Apple 的父类,但不知道具体是哪一层


3. 工程意义

PESC 的真正含义是:

场景选择
主要用于读取? extends T
主要用于写入? super T

4. API 设计中的体现

Java API 中的经典例子:

public static <T> void copy(    List<? super T> dest,    List<? extends T> src)

设计意图极为清晰:


六、泛型的实现机制:类型擦除

1. 核心事实

JVM 并不真正理解泛型

在虚拟机层面:


2. 泛型擦除的过程

编译阶段:


3. 为什么要擦除?

本质原因:

历史兼容性


4. 带来的代价

由于擦除:


七、类型系统视角

泛型问题本质是一个类型系统问题。


1. 类型变化关系

设:


协变(covariant)

A ≤ B  ⇒  f(A) ≤ f(B)

逆变(contravariant)

A ≤ B  ⇒  f(B) ≤ f(A)

不变(invariant)

f(A) 与 f(B) 无关

2. Java 中的选择

形态类型关系
List不变
? extends T协变
? super T逆变

3. 本质联系


八、对泛型的整体认知

我们可以把 Java 泛型总结为:

一套在“静态类型系统约束”与“历史兼容性”之间权衡的设计


三层模型

层次含义
语法层<T>extendssuper
语义层类型参数化与类型约束
实现层类型擦除与桥方法

九、总结

1. 泛型的本质


2. 泛型的核心价值


3. 使用哲学

关联内容(自动生成)