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

Java 泛型类型擦除不是 bug,是为兼容老代码做的主动设计。它让 `List 泛型参数(如 `T`)在字节码里不存在,JVM 不认识 `List 泛型安全靠编译器插入强制转换实现,不是靠运行时校验。例如: // 编译前别把泛型当运行时类型用
别误以为“写了泛型就真有类型信息”
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 大师之旅:从入门到精通的终极指南











