Java 泛型 超详细入门教程
·
Java 泛型(Generics)是 JDK 5 引入的特性,核心作用是:在编译时检查类型安全,避免运行时类型转换异常,同时让代码更通用、更简洁。
简单说:泛型 = 参数化类型,把类型当作参数传递,让类 / 方法 / 接口可以适配多种数据类型。
一、为什么要用泛型?(痛点对比)
1. 没有泛型的代码(不安全、繁琐)
java
运行
List list = new ArrayList();
list.add("Hello");
list.add(100); // 可以存任意类型,很危险
// 取出时必须强转,容易报 ClassCastException
String str = (String) list.get(1); // 运行时报错!
问题:
- 编译不报错,运行时才抛异常
- 每次取值都要强制类型转换
- 集合可以存任意类型,类型不安全
2. 使用泛型的代码(安全、简洁)
java
运行
List<String> list = new ArrayList<>();
list.add("Hello");
// list.add(100); 编译直接报错!类型不匹配
String str = list.get(0); // 无需强转
优势:
- 编译期类型检查,提前发现错误
- 自动类型转换,代码更简洁
- 集合只能存指定类型,类型安全
二、泛型的三种使用形式
1. 泛型类 / 泛型接口
把泛型定义在类 / 接口上,整个类内都可以使用这个泛型类型。
语法
java
运行
class 类名<T> { }
interface 接口名<T> { }
<T>就是类型参数,可以写任意标识(常用 T、E、K、V)- 使用时传入具体类型(如
String、Integer)
示例:通用泛型类
java
运行
// 泛型类:T 是类型参数,使用时才确定具体类型
public class Box<T> {
private T data;
public void set(T data) {
this.data = data;
}
public T get() {
return data;
}
}
// 使用
Box<String> stringBox = new Box<>();
stringBox.set("Java");
String s = stringBox.get();
Box<Integer> intBox = new Box<>();
intBox.set(100);
Integer i = intBox.get();
2. 泛型方法
把泛型定义在方法上,方法独立于类拥有自己的类型参数。
语法
java
运行
修饰符 <T> 返回值类型 方法名(参数列表) { }
<T> 必须写在返回值前面。
示例:通用泛型方法
java
运行
public class GenericMethod {
// 泛型方法:打印任意类型的数组
public static <T> void printArray(T[] array) {
for (T t : array) {
System.out.println(t);
}
}
public static void main(String[] args) {
Integer[] intArr = {1,2,3};
String[] strArr = {"A","B","C"};
printArray(intArr); // 自动适配 Integer
printArray(strArr); // 自动适配 String
}
}
三、泛型常用通配符
1. 无界通配符 <?>
表示任意类型,常用于只读取数据、不修改的场景。
java
运行
public static void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
✅ 可以接收 List<String>、List<Integer> 等任意 List
2. 上界通配符 <? extends 类>
只能接收 该类及其子类(读安全,写不安全)
java
运行
// 只能传入 Number 或其子类(Integer、Double等)
public static void getNum(List<? extends Number> list) { }
3. 下界通配符 <? super 类>
只能接收 该类及其父类(写安全)
java
运行
// 只能传入 Integer 或其父类(Number、Object)
public static void addNum(List<? super Integer> list) {
list.add(100);
}
四、泛型常用类型参数命名规范
行业通用写法,见名知意:
T:Type(任意类型)E:Element(元素,集合常用)K:Key(键)V:Value(值)N:Number(数字)
五、泛型重要特性:类型擦除
Java 泛型是伪泛型,只在编译阶段有效,编译成 class 文件后,泛型信息会被全部删除。
示例:
java
运行
List<String> strList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
// 编译后:两者的 class 完全一样,都是 List
System.out.println(strList.getClass() == intList.getClass()); // true
⚠️ 注意:
- 不能用基本类型(
int/double)作为泛型参数,必须用包装类(Integer/Double) - 不能创建泛型数组:
T[] arr = new T[10];❌ 错误
六、泛型的好处总结
- 类型安全:编译期检查,避免运行时类型转换异常
- 消除强制转换:代码更简洁、可读性更高
- 代码复用:一套逻辑适配多种类型,不用重复写代码
- 提高性能:避免运行时类型检查
更多推荐


所有评论(0)