Java 泛型概述
Java 泛型(Generics) 是 JDK 1.5 引入的一项功能,允许在类、接口和方法中定义具有参数化类型的代码。泛型通过在编译时进行类型检查,提高了代码的安全性和可读性,减少了类型转换的需求。
泛型的优势
类型安全:在编译时检查类型,避免运行时的 ClassCastException。
代码重用性:支持定义通用的类、接口和方法,适用于多种数据类型。
可读性和维护性:代码更加清晰,减少了显式类型转换的需要。
泛型的基本语法
- 泛型类
1 | package com.qust; |
1 | public class Main { |
- 泛型接口
1 | // 定义一个泛型接口 |
1 | package com.qust; |
1 | public class Main { |
- 泛型方法
1 | package com.qust; |
泛型的类型限制
通配符 ?
表示未知类型,可用于读取时不确定具体类型。
1
2
3
4
5public static void printList(List<?> list) {
for (Object item : list) {
System.out.println(item);
}
}
边界限定
上界通配符:<? extends T> 表示类型是 T 或其子类。
1
2
3
4
5public static void printNumbers(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}下界通配符:<? super T> 表示类型是 T 或其父类。
1
2
3public static void addNumbers(List<? super Integer> list) {
list.add(1); // 允许添加 Integer 或其子类
}
类型参数边界
限制泛型的范围。
1
2
3
4
5
6
7
8
9
10
11public class Box<T extends Number> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
泛型的注意事项
类型擦除
Java 泛型是通过类型擦除实现的,编译器在编译时会将泛型信息去掉,转换为原始类型(如 Object)。
- 因此,不能在运行时获取泛型类型参数的信息,例如 List
和 List 在运行时是相同的。
- 因此,不能在运行时获取泛型类型参数的信息,例如 List
泛型不能用于静态字段或方法
由于泛型类型在编译时确定,而静态成员属于类本身,与实例无关,因此泛型不能应用于静态成员。
1
2
3
4
5
6
7public class GenericClass {
// 静态变量不能使用泛型
// private static T staticVar;
// 静态方法也不能使用泛型
// public static T getStaticValue() { return null; }
}
不能创建泛型数组
1
2// 不允许直接创建泛型数组
List[] array = new ArrayList[10]; // 编译错误原始类型
1 | Res res = new Res(); |
没有指定泛型的数据类型,导致类型不安全。
常见应用场景
集合框架:Java 的集合框架(如 ArrayList、HashMap 等)广泛使用了泛型。
工具类:如 java.util.Collections 提供了许多泛型方法。
类型安全容器:泛型可以实现自定义的类型安全容器。