泛型是jdk5引入的参数化类型机制,本质是将类型作为参数传递,实现编译期类型安全检查与代码复用;它解决原始集合类型不安全、强制转换繁琐、错误延迟到运行时等问题,但受类型擦除影响,运行时无泛型信息,导致无法new t[]、不能instanceof泛型类型、静态成员不可用泛型参数等陷阱。

直接上手练,重点不是背题,而是理解泛型在真实代码中怎么用、为什么这么用、哪里会踩坑。
从集合操作开始练手感
这是最贴近日常开发的切入点。别光写 List<string></string> 这种简单例子,要动手改写一段“没用泛型”的老代码:
- 找一个原始
List(没声明泛型)的集合操作逻辑,比如遍历、过滤、转换 - 把它改成带泛型的版本,明确指定元素类型(如
List<user></user>、Map<string integer></string>) - 观察编译器提示:删掉泛型后是否出现 unchecked 警告?加了泛型后是否自动帮你避免了
(User) obj这类强制转换?
自己写泛型工具类练设计能力
面试常考“能不能写个通用方法”,不是考语法,是考你能不能抽象共性:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 写一个
<t> T findFirst(List<t> list, Predicate<t> condition)</t></t></t>—— 理解方法级泛型如何独立于类存在 - 写一个
<k v> Map<k v> toMap(List extends Object> src, Function<object k> keyMapper, Function<object v> valueMapper)</object></object></k></k>—— 练习多类型参数 + 通配符 + 函数式接口组合 - 故意传错类型试试:比如把
String[]传给期望Integer[]的泛型方法,看编译报错位置和提示信息
专攻擦除相关的“陷阱题”
大厂最爱问“为什么不能 new T[]”、“instanceof List
- 写两行代码:
List<string> a = new ArrayList(); List<integer> b = new ArrayList();</integer></string>,然后打印a.getClass() == b.getClass()—— 结果是 true - 尝试写
new ArrayList<string>[10]</string>或T[] arr = new T[5],看编译器报什么错 - 写一个泛型类,里面加个
static T cache,编译失败后想想:静态成员属于类本身,而泛型类型参数只在实例化时才确定,两者根本对不上
结合通配符做类型兼容练习
很多同学知道 extends Number> 和 super Integer> 的定义,但不会用。练法很直接:
- 写一个方法
void addNumbers(List super Integer> list),试着往里 add(1)、add(100L)、add(new Object()),看哪些能过 - 写一个方法
Number getFirst(List extends Number> list),试着 get(0).intValue()、get(0).doubleValue(),再试试list.add(new Integer(1))—— 为什么加不了? - 对比
List<object></object>和List extends Object>的使用边界:前者能 add 任意对象,后者只能读,不能写
不复杂但容易忽略:每写一行泛型代码,都问自己一句——这行在运行时实际是什么类型?编译器帮我省了哪步手动转换?如果擦除后出问题,会是什么表现?
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










