避免原始类型风险的核心是全程启用泛型约束:强制参数化声明(如List<User>)、IDE/构建工具设为Error、加固反射与反序列化场景(如TypeReference)、纳入团队规范与CI拦截。

避免原始类型(raw type)风险的核心,是让泛型约束从编码开始就全程生效——原始类型等于主动关闭编译器的类型检查,把本该在写入时拦截的错误,推迟到取值时才暴露为 ClassCastException。
强制使用参数化声明
所有泛型集合、工具类引用必须显式标注类型参数,禁止裸写 List、Map、Set 等。
-
正确写法:
List<User> users = new ArrayList<>();、Map<String, Integer> cache = new HashMap<>(); -
错误写法:
List users = new ArrayList();(哪怕后面 add 的全是 User,也失去编译期保护) - 方法签名同样要参数化:
public <T> T parse(String json, Class<T> type),而非public Object parse(String json)
IDE 和构建工具设防
借助开发环境自动拦截原始类型用法,比靠人眼审查更可靠。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- IntelliJ:Settings → Editor → Inspections → “Raw use of parameterized class” → 设为 Error
- Eclipse:Preferences → Java → Compiler → Errors/Warnings → “Unchecked generic type operation” → 设为 Error
- Maven 项目中启用
maven-compiler-plugin并配置source/target为 8+,确保泛型语法被严格校验
封堵反射与反序列化的绕过路径
原始类型常在 JSON 解析、RPC 响应、反射调用等场景“偷偷复活”,必须额外加固。
立即学习“Java免费学习笔记(深入)”;
- Jackson 反序列化不用
mapper.readValue(json, List.class),改用mapper.readValue(json, new TypeReference<List<Order>>() {}) - 遇到旧接口返回原始
List,封装安全转换方法:safeCastList(rawList, Product.class),内部逐项用Product.class.isInstance(item)校验 - 禁止对反序列化结果做无条件强转:
(List<Product>) rawList是高危操作,即使加了@SuppressWarnings("unchecked")也不行
统一团队规范与 Code Review 检查点
原始类型不是技术问题,而是协作习惯问题。需明确纳入准入红线。
- 代码规范文档中单列一条:“禁止任何 raw type 出现在生产代码中,包括字段、局部变量、方法参数、返回值”
- PR 检查清单加入:“是否所有集合/泛型类均带完整类型参数?”
- CI 流程中集成
errorprone或checkstyle插件,自动扫描rawtypes警告并阻断构建

















