泛型类通过类型参数实现类型安全复用,声明时用占位符、实例化时指定具体引用类型,配合extends/super通配符保障灵活性与安全性,但受类型擦除限制无法运行时判型或new t()。

直接用泛型类封装通用逻辑,核心是把“类型”变成参数,让编译器替你盯住类型匹配——写对一次,所有类型都能安全复用。
定义带类型参数的泛型类
在类名后加
- 声明时只写占位符,不写具体类型,例如:
private T data;、public void set(T value) - T 可以有边界约束,如
,确保能调用 doubleValue()等共通方法 - 避免用原始类型(如 Object)替代泛型,否则失去类型检查能力
实例化时指定具体类型
创建对象时填入真实类型,编译器立即锁定该实例的合法操作范围:
-
Box<string> strBox = new Box();</string>→ 只允许存 String,取出来直接是 String,不用强转 -
Box<integer> intBox = new Box();</integer>→ 存 42 合法,存 "abc" 编译报错 - 尖括号里的类型必须是引用类型,不能写
Box<int></int>(可用Integer)
配合通配符提升灵活性与安全性
当方法接收或返回泛型容器时,用通配符避免类型僵化,同时守住读/写边界:
- 只读场景用 extends T>:例如
printAll(List extends Number> list),可传入List<integer></integer>或List<double></double>,但不能往里 add 非 null 元素 - 只写场景用 super T>:例如
addIntegers(Collection super Integer> coll),可接受Collection<number></number>或Collection<object></object>,保证 Integer 安全写入 - 完全未知类型用 >:仅限调用无参方法(如
size()、clear()),禁止读写具体类型数据
注意类型擦除带来的限制
泛型信息在运行时不存在,所以某些操作需绕开擦除机制:
- 不能用
if (t instanceof T)判断类型——T 在运行时已变成 Object 或上界类型 - 不能通过泛型参数创建实例:
new T()编译失败;可用 Supplier 或传入 Class 对象规避 - 静态方法无法直接访问类的泛型参数,需定义自己的类型参数:
public static <e> E getFirst(List<e> list)</e></e>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











