JAVA 泛型(Generic)是 Java 中的一种类型参数化机制,简单说就是“在定义类、接口、方法时,不指定具体类型,而是用一个符号(比如 T、E)代替,在使用时再明确具体类型”。
它的核心作用是让代码更通用、更安全,举个生活中的例子你就明白了:
🌰 生活类比:快递盒子
普通盒子(无泛型):只能装固定类型的东西(比如“只能装衣服的盒子”“只能装书籍的盒子”)。
泛型盒子:盒子上贴一个标签(比如“装衣服”“装书籍”),贴什么标签就装什么,灵活通用。
在 Java 中,这个“标签”就是泛型参数(比如 T),“盒子”可以是类、接口、方法。
✅ 代码例子:从“不通用”到“泛型”
1. 没有泛型的问题
假设你想写一个“装数据的容器”,如果不用泛型,只能为每种类型写一个类:
// 只能装 Integer 的容器
class IntBox {
private Integer value;
public void set(Integer value) { this.value = value; }
public Integer get() { return value; }
}
// 只能装 String 的容器
class StringBox {
private String value;
public void set(String value) { this.value = value; }
public String get() { return value; }
}
问题:类型多了会导致代码重复(每个类型都要写一个类),而且取出数据时可能需要强制类型转换(如果用 Object 代替,会有类型安全问题)。
2. 用泛型解决
定义一个带泛型参数 T 的通用容器:
// 泛型类:T 是类型参数(可以理解为“占位符”)
class Box
private T value; // 用 T 表示“某种类型”
public void set(T value) { this.value = value; } // 接收 T 类型的值
public T get() { return value; } // 返回 T 类型的值
}
使用时指定具体类型:
public class Main {
public static void main(String[] args) {
// 明确 T 是 Integer:只能装整数
Box
intBox.set(100); // 正确:只能传 Integer
Integer num = intBox.get(); // 无需强转,直接得到 Integer
// 明确 T 是 String:只能装字符串
Box
strBox.set("hello"); // 正确:只能传 String
String str = strBox.get(); // 无需强转,直接得到 String
}
}
🔑 泛型的核心优势
代码复用:一个泛型类/方法可以适配多种类型,不用重复编写类似代码(比如上面的 Box
类型安全:编译期就会检查类型是否匹配,避免了“把 String 放进 Integer 容器”的错误(如果不用泛型,用 Object 存放,编译期不报错,运行时可能抛异常)。
避免强制转换:取出数据时不用手动强转(比如 (Integer) object),减少代码冗余和出错风险。
📌 常见泛型符号
T(Type):表示“某种类型”(最常用)。
E(Element):表示集合中的“元素类型”(比如 List
K(Key)、V(Value):表示键值对中的“键”和“值”(比如 Map
🌐 实际应用:集合框架
Java 中的 List、Map 等集合都是泛型的典型应用:
// List
List
list.add("a"); // 正确
list.add(123); // 编译报错(类型不匹配)
// Map
Map
map.put(1, "one"); // 正确
✅ 总结
泛型就是“给代码加个类型占位符,使用时再指定具体类型”,目的是让代码更通用、更安全、更少冗余。就像一个“万能模具”,你告诉它要做什么形状(类型),它就给你做出对应形状的产品,而不用为每种形状单独做一个模具。