练好java泛型关键在于理解擦除机制、动手验证与对比差异:通过getclass()验证运行时类型相同,反射对比getgenerictype()与gettype(),实例化泛型数组和instanceof t报错等实践深化认知。

练好Java泛型面试题,关键不是死记答案,而是理解机制、动手验证、对比差异。下面几个方向最有效:
从擦除机制反推行为
泛型的“运行时不存在”是几乎所有难点的根源。练的时候别只背结论,要自己写代码验证:
- 写一个
List<string></string>和一个List<integer></integer>,用getClass()打印它们的运行时类——结果都是ArrayList - 尝试用反射获取
field.getGenericType()(比如字段声明为private List<date> dates;</date>),再和field.getType()对比,体会“泛型信息只在声明处保留” - 写个方法
public static <t> void test(T t) { System.out.println(t instanceof String); }</t>——编译直接报错,因为T擦除后是Object,无法做instanceof判断
用通配符解决真实传参问题
面试常考“为什么 List<string></string> 不是 List<object></object> 的子类型”,练法就是写实际会出错的场景:
- 定义方法
void process(List<number> list)</number>,然后传入ArrayList<integer></integer>——编译失败;改成void process(List extends Number> list)就能通过 - 写一个添加元素的方法
void addOne(List super Integer> list),试试能否往里加new Integer(1)或new Long(2),理解下界的作用边界 - 对比
>、extends T>、super T>在读/写操作上的限制,画个表格总结(比如“上界可读不可写,下界可写不可读”)
动手改写经典工具类
光看 Box<t></t> 示例太单薄。挑 JDK 里真实用到泛型的地方,自己重写简化版:
- 手写一个
Pair<k v></k>,带getKey()/getValue(),再写个public static <k v> Pair<k v> of(K k, V v)</k></k>工厂方法 - 模仿
Optional<t></t>:实现of()、empty()、isPresent()、get(),注意get()抛异常时不能 throw T - 写个泛型单例容器
GenericHolder<t></t>,里面存一个static final Map<class>, Object></class>,用Class<t></t>当 key 存取不同类型的实例——这是绕过擦除的常用技巧
故意写错再分析报错
很多知识点只有踩过坑才真正记住。专门写几段“看起来合理但编译不过”的代码:
-
T[] arr = new T[10];→ 报错:Cannot create a generic array -
if (t instanceof T)→ 报错:Illegal generic type for instanceof -
class A<t> implements Comparable<t></t></t>+class B extends A<string></string>→ 编译通过;但改成class B extends A<string> implements Comparable<b></b></string>就可能冲突,理解桥方法生成逻辑
不复杂但容易忽略:每次练习后,用 javap -c 看字节码,确认泛型是否真被擦除、桥方法是否存在——眼见为实。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











