java泛型类型擦除是为兼容老代码的主动设计,运行时无泛型信息,安全依赖编译器插入强转;静态上下文无法访问泛型参数;泛型不变性与数组协变冲突导致new t[]非法。

别把泛型当运行时类型用
泛型参数(如 `T`)在字节码里不存在,JVM 不认识 `List
-
`instanceof List
` 编译失败 ——只能写 `instanceof List`; - `new T()` 直接报错——因为 `T` 已擦成 `Object` 或上界类型,构造器无法定位;
-
`list.getClass() == list2.getClass()` 返回 true,哪怕一个是 `List
`,一个是 `List `。
别误以为“写了泛型就真有类型信息”
泛型安全靠编译器插入强制转换实现,不是靠运行时校验。例如:
// 编译前
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
List<string> list = new ArrayList();<br>
list.add("ok");<br>
String s = list.get(0); // 看似直接赋值</string>
// 编译后等效
List list = new ArrayList();<br>
list.add("ok");<br>
String s = (String) list.get(0); // 编译器偷偷加的强转
一旦绕过编译检查(比如用原始类型 `List raw = list; raw.add(123)`),运行时就会 `ClassCastException`——这不是泛型失效,而是你主动破坏了编译器建的安全护栏。
别指望静态上下文能访问类泛型参数
静态方法、静态字段属于类,而泛型参数属于实例。擦除后,类层面根本没有 `T` 的踪影:
- `public static T getValue()` 编译不通过;
- 正确写法是声明自己的类型参数:`public static
T getValue()` ; - 类中的 `static List
` 字段非法,必须写成 `static List` 或 `static List
别混淆“数组协变”和“泛型不变”带来的限制
Java 数组是协变的(`String[]` 是 `Object[]` 子类型),但泛型是不变的(`List
- `new T[10]` 编译错误——JVM 创建数组需确切类型,但 `T` 已擦除;
-
`new List
[10]` 同样非法 ——擦除后是 `List[10]`,但 JVM 要求泛型数组元素类型可检,而 `List` 没有运行时泛型身份; - 替代方案:用 `ArrayList
`,或传入 `Class ` 配合反射创建(如 `Array.newInstance(clazz, size)`)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










