一、为什么需要泛型?
在泛型出现之前(JDK5 之前),Java 集合(比如 HashMap、ArrayList)只能存储 Object 类型的对象,会带来两个致命问题:
- 类型不安全:可以往集合里存任意类型的对象,运行时可能抛出类型转换异常。
- 需要手动强制类型转换:取数据时必须手动转换成目标类型,代码繁琐且容易出错。
反面例子(无泛型的 HashMap):
public static void main(String[] args) {
// 无泛型的 HashMap:默认存 object 类型
Map map = new HashMap();
// 1. 可以存任意类型(字符串 key + 整数 value、字符串 key + 字符串 Value)
map.put("年龄", 20);
map.put("姓名", "张三");
// 甚至能存不相关的类型(比如 key 是整数,Value 是数组)
map.put(100, new int[]{1, 2, 3});
// 2. 取值时必须手动强转,且容易出错
// 正确转换:年龄是整数
int age = (int) map.get("年龄");
System.out.println("年龄:" + age);
// 错误转换:姓名是字符串,强转成整数会抛出 ClassCastException
// int name = (int) map.get("姓名"); // 运行时报错
}
问题总结:
- 编译时无法检查类型错误(比如往存'年龄'的 Map 里存字符串),只有运行时才会报错
- 每次取值都要强制类型转换,代码冗余且容易出错。
而泛型的核心作用就是:在编译阶段限制集合/类的类型,保证类型安全,同时避免手动类型转换。
二、泛型的核心概念
2.1 定义
泛型(Generic)是 JDK5 引入的特性,允许在定义类、接口、方法时,使用'类型参数'(比如)来表示未知类型,使用时再指定具体类型(比如<String, Integer>)。
可以把泛型理解成'类型的占位符':
- 定义时:用 <K, V>等符号占位置(T = type,K = key,V = value,只是约定俗称的命名,用其他的字母也可以)


