Java原始类型(Raw Type)是泛型擦除后的裸类名,如List<String>擦除为List;它绕过编译期类型检查,导致运行时类型不安全,虽为向后兼容而保留,但应尽量避免使用。

Java 中的原始类型(Raw Type)是泛型类型擦除后留下的“裸”类名,比如 List<String> 擦除后就是 List。它不是语法错误,但会绕过编译期泛型检查,带来隐性风险——这既是历史兼容的设计妥协,也是日常开发中容易踩坑的盲区。
RawType如何绕过泛型检查
声明原始类型时,编译器不再校验元素类型,所有泛型约束失效:
-
List rawList = new ArrayList<Integer>();编译通过,但rawList.add("hello")也能成功——字符串被悄悄加进本该只存整数的集合 - 调用泛型方法如
rawList.get(0)返回Object,需手动强转,失去类型安全保证 - 若原始类型作为参数传入泛型方法(如
process(List<String> list)),传入List会触发编译警告(unchecked warning),但不报错
擦除下RawType的真实行为表现
运行时,JVM 看不到任何泛型信息,RawType 和参数化类型共享同一 Class 对象:
-
new ArrayList<String>().getClass() == new ArrayList<Integer>().getClass()结果为true - 反射调用
add(Object)方法可向任意泛型集合插入任意类型对象,例如向ArrayList<Integer>插入字符串,后续取值时抛出ClassCastException - 泛型数组创建被禁止(
new List<String>[10]编译失败),但原始类型数组允许(new List[10]合法),进一步暴露类型不安全
为什么RawType仍被保留
核心是为了向后兼容 JDK 5 之前的代码:
- 旧版 Java 类库(如
Vector、HashMap)没有泛型,新代码需能与之交互 - 泛型接口实现类可以使用 RawType 实现(如
class MyList implements List),虽不推荐但合法 - 某些框架反射场景(如 Spring 的泛型 Bean 解析)依赖 RawType 获取底层 Class,再结合
ParameterizedType还原类型信息
规避建议:少用、禁用、替代
除非明确需要兼容或反射操作,否则应主动规避 RawType:
- 启用编译器选项
-Xlint:unchecked,让 RawType 使用显式报警 - 用通配符替代,如
List<?>表示未知类型,比List更安全且语义清晰 - 工具类中避免返回 RawType,优先用
<T> List<T>泛型方法封装 - IDE 设置检查项(如 IntelliJ 的 “Raw use of parameterized class” 提示)并设为 warning 或 error

















