Java 泛型:核心概念与实战解析
·
Java 泛型(Generics)是 JDK 5 引入的核心特性,本质是参数化类型—— 允许类、接口、方法在定义时声明类型参数,使用时再指定具体类型,既能实现代码复用,又能在编译期检查类型安全,避免手动类型转换(向下转型)的繁琐与 ClassCastException 风险。
一、核心价值
- 类型安全:编译期校验类型,杜绝运行时类型转换错误(比如把 String 放入 Integer 集合);
- 代码复用:一套泛型代码适配多种类型,无需为不同类型重复编写逻辑;
- 可读性提升:代码中明确标注类型意图,无需通过注释说明集合 / 方法处理的类型。
二、核心使用场景
1. 泛型类 / 接口
定义类 / 接口时声明类型参数(用<T>表示,T 为类型占位符,可自定义名称如 E、K、V),使用时指定具体类型。
java
运行
// 泛型类定义(T为类型参数)
public class GenericBox<T> {
private T content;
// 泛型方法(与类的类型参数一致)
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
// 测试
public static void main(String[] args) {
// 使用时指定String类型
GenericBox<String> stringBox = new GenericBox<>();
stringBox.setContent("Java泛型");
String content = stringBox.getContent(); // 无需强制转换
// 指定Integer类型
GenericBox<Integer> intBox = new GenericBox<>();
intBox.setContent(100);
Integer num = intBox.getContent();
}
}
注:泛型接口同理(如
List<T>、Map<K,V>都是 Java 内置泛型接口)。
2. 泛型方法
方法级别独立声明类型参数(即使所在类不是泛型类),语法:<类型参数> 返回值类型 方法名(参数列表)。
java
运行
public class GenericMethodDemo {
// 泛型方法:T为独立类型参数
public static <T> T getFirstElement(T[] array) {
if (array == null || array.length == 0) {
return null;
}
return array[0];
}
// 测试
public static void main(String[] args) {
String[] strArr = {"a", "b", "c"};
String firstStr = getFirstElement(strArr); // 自动推断T为String
Integer[] intArr = {1, 2, 3};
Integer firstInt = getFirstElement(intArr); // 自动推断T为Integer
}
}
3. 泛型通配符
解决泛型 “不可变” 问题(比如List<String>不是List<Object>的子类),核心有 3 种通配符:
?:无界通配符,适配任意类型(只能读,不能写,避免类型污染);? extends T:上界通配符,适配 T 及 T 的子类(只能读 T 类型数据);? super T:下界通配符,适配 T 及 T 的父类(只能写 T 类型数据)。
示例:
java
运行
// 上界通配符:接收List<Integer>、List<Number>等
public static double sum(List<? extends Number> list) {
double total = 0;
for (Number num : list) {
total += num.doubleValue();
}
return total;
}
// 下界通配符:接收List<Integer>、List<Object>等
public static void addInt(List<? super Integer> list) {
list.add(100); // 可写入Integer类型
}
三、关键注意事项
- 泛型擦除:Java 泛型仅存在于编译期,运行时类型参数会被擦除(替换为 Object 或上界类型),因此:
- 不能用
new T()(运行时不知道 T 的具体类型); - 不能判断
if (obj instanceof List<T>); - 不能创建泛型数组(
new List<String>[10]非法)。
- 不能用
- 基本类型不支持:泛型参数只能是引用类型,需用包装类(如
List<Integer>而非List<int>)。 - 静态成员与泛型:静态方法 / 变量不能使用类的泛型参数(静态成员属于类,初始化时泛型参数未指定)。
- 泛型继承规则:
GenericBox<String>不是GenericBox<Object>的子类,需用通配符兼容。
四、典型应用场景
- 集合框架:
ArrayList<T>、HashMap<K,V>是泛型最核心的应用; - 自定义工具类:如通用的缓存工具
Cache<K,V>、数据转换器Converter<F,T>; - 框架开发:Spring 的
ParameterizedTypeReference<T>、MyBatis 的Mapper<T>均依赖泛型; - 函数式编程:
Supplier<T>、Consumer<T>等函数式接口基于泛型实现类型适配。
五、总结
Java 泛型是 “编译期语法糖”,核心是通过参数化类型实现类型安全 + 代码复用,掌握泛型类、泛型方法、通配符三大核心,能大幅提升代码的健壮性与复用性。实际开发中,优先使用泛型替代原始类型(如List→List<String>),结合通配符解决泛型兼容性问题,规避类型转换风险。
更多推荐


所有评论(0)