java泛型是编译期类型契约,解决运行时classcastexception问题;通过泛型类、方法、接口实现类型安全;受类型擦除限制,不支持基本类型、泛型数组等。

从零开始学 Java 泛型,关键不是背语法,而是理解它解决什么问题、为什么这样设计。泛型本质是“编译期的类型契约”——你在写代码时就明确告诉编译器:“这个容器只装 String”,“这个方法只处理 Number 子类”,而不是等到运行时才崩溃。
先搞懂它为什么存在
不加泛型的集合就像一个没贴标签的抽屉:你可以往 ArrayList 里塞字符串、整数、日期,甚至一只猫。取出来时必须手动强转:(String) list.get(0)。一旦放错、取错,程序一运行就抛 ClassCastException。
泛型把这种风险拦在编译阶段:
-
List<string> list = new ArrayList();</string>→ 编译器立刻阻止你写list.add(123) -
String s = list.get(0);→ 不用强转,类型已知,安全又简洁
掌握三类基本写法
泛型类:定义通用模板,比如自己写一个盒子
public class Box<t> { private T content; public void setContent(T c) { this.content = c; } public T getContent() { return content; } }</t>- 使用:
Box<string> box = new Box(); box.setContent("ok"); String s = box.getContent();</string>
泛型方法:方法本身带类型参数,和所在类是否泛型无关
public static <t> void printArray(T[] arr) { for (T item : arr) System.out.println(item); }</t>- 调用:
printArray(new String[]{"a", "b"});或printArray(new Integer[]{1, 2});
泛型接口:定义通用行为规范
public interface Processor<t> { T process(T input); }</t>- 实现:
class StringUppercase implements Processor<string> { public String process(String s) { return s.toUpperCase(); } }</string>
注意几个硬性限制
Java 泛型基于“类型擦除”,这意味着:
- 运行时拿不到泛型信息 ——
list.getClass()永远是ArrayList.class,不是ArrayList<string>.class</string> - 不能用基本类型当泛型参数 ——
List<int></int>❌,只能用包装类List<integer></integer>✅ - 不能直接创建泛型数组 ——
new ArrayList<string>[10]</string>❌,可改用new ArrayList[10](但会警告)或用ArrayList<list>></list> - 泛型类的静态成员无法访问类型参数 ——
static T value;❌,因为静态属于类,而泛型类型属于实例
从集合入手边练边学
别空看概念,打开 IDE 直接敲:
- 写一个
Pair<k v></k>类,封装键值对,带getKey()/getValue() - 用
Map<string list>></string>存储学生成绩,练习嵌套泛型 - 对比有无泛型的
ArrayList使用差异:加错类型、取值是否强转、IDE 提示变化
泛型不是炫技工具,它是帮你少写 cast、少 debug ClassCastException 的日常防护机制。写熟了,你会发现它比想象中自然得多。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











