Java泛型擦除是编译器将类型参数替换为Object或上界类型并插入强制转换,JVM运行时无泛型信息;故无法new T[]、instanceof List,反射也拿不到实际类型参数。

Java泛型擦除不是“删除”,而是编译器在生成字节码前,把所有
javac怎么擦:看字节码最真实
泛型信息只活在源码和编译期,javac一过,就只剩原始类型。用javap -c反编译就能验证:
-
public T get()编译后变成public Object get(),返回值是areturn(Object引用返回) - 调用方拿到
Object后,编译器悄悄插一句checkcast #String——这就是你写list.get(0)却不用手动强转的原因 -
Box<integer></integer>和Box<string></string>的getClass()完全相同,因为运行时只有Box一个类
为什么不能 new T[10] 或 instanceof List
这些操作依赖运行时类型信息,但擦除后根本不存在List<string></string>这个类型——JVM只认List。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
-
new T[10]❌ 编译报错:类型参数在运行时是未知的,数组创建需要具体组件类型 -
if (list instanceof List<string>)</string>❌ 编译不通过:泛型类型不可作为instanceof右操作数 - 想绕过?只能用
list instanceof List && !list.isEmpty() && list.get(0) instanceof String——但这是业务逻辑判断,不是类型检查
擦除带来的坑:反射拿不到泛型实际类型
你用field.getGenericType()能拿到java.lang.reflect.ParameterizedType,但调用getActualTypeArguments()返回的仍是Class>,不是String.class。
立即学习“Java免费学习笔记(深入)”;
- 原因:泛型类型参数在字节码里只存于
Signature属性(仅供编译器/IDE用),Class对象本身不携带运行时泛型实例信息 - workaround:靠构造函数传入
Class<t></t>,比如new GenericArray<string>(String.class, 5)</string> - Spring、MyBatis 等框架正是靠这种“类型令牌”+反射+字节码分析(如
ASM)来还原泛型上下文
真正难的不是理解“擦除”,而是意识到:所有你以为在运行时能拿到的泛型类型,其实都是编译器帮你记在源码注释、方法签名或调试信息里的幻觉——JVM眼里,只有Object和强制转换指令。

















