首页/开发/代码质量与评审速查/Error Prone:Java 编译期检查
规范与静态检查65 条

Error Prone:Java 编译期检查

Error Prone 是 Google 的 javac 插件:编译期直接报出常见错误,如 ReturnValueIgnored(忽略有意义返回值)、DeadException(创建异常未抛出)、EqualsIncompatibleType。

Error Prone 是什么

Error Prone 是 Google 开发的 javac 编译器插件,在编译阶段直接检查代码模式:忽略有意义的返回值、创建了异常对象却没有抛出、equals 两侧类型不可能相等这类常见错误。因为它挂在 javac 上随编译运行,不需要额外的扫描步骤,也不容易被绕过;规则可配置为警告或直接让编译失败。

基本信息

定位编译期检查,javac 插件
接入方式Maven / Gradle / Bazel 构建插件
告警级别建议级与错误级,可逐条调整
版本要求插件版本需与 JDK、构建工具匹配
常见冲突字节码生成类工具(如 Lombok)

典型使用场景

  • 在编译期拦住被丢弃的返回值,避免静默失效的调用
  • CI 中编译即扫描,不额外增加流水线阶段
  • JDK 大版本升级时,用它暴露历史代码里的疏忽
  • 把团队约定写成自定义检查器,随编译一起生效
  • 对长期没人敢动的模块先以警告模式收集问题

典型告警读法

告警含义处理
ReturnValueIgnored有意义的返回值被丢弃赋值使用,或显式忽略并说明原因
DeadException创建异常对象但没有抛出补上抛出语句或删除无用构造
EqualsIncompatibleTypeequals 两侧类型不可能相等检查是否传错类型或写错比较对象
CheckReturnValue标注该检查的方法返回值未被使用处理返回值,或调整标注范围

一个返回值告警的例子

一个返回值告警的例子
// 告警:String 不可变,replace 的结果被丢弃,代码实际没生效
user.getName().replace(" ", "");

// 修法一:接收返回值
String normalized = user.getName().replace(" ", "");

// 修法二:确实不需要结果时显式表达意图,并说明原因
// 忽略返回值:此处仅为触发惰性加载
user.getName();
与 Lombok 等字节码生成工具同时使用时,需要把两者版本对齐,并把确认的误报加进豁免清单;否则编译期报错会挡住正常构建,团队最后只能整体关掉插件。
上线节奏建议:先全量以警告级别运行,收集误报并逐条清理;稳定之后再把确认的规则提升为错误级别,避免第一天就卡住所有人的构建。

易错点

  • 全量检查不裁剪:误报拉低信任度,编译时间也明显变长
  • 与 Lombok 等字节码工具版本不匹配:编译报错与业务代码无关,排查成本高
  • 一次性把错误级别拉满:历史代码集体编译失败,团队直接关闭插件
  • 忽略告警全靠注释抑制:没有原因记录,问题失去可追溯性
  • 只在一个构建工具里接入:其余入口绕过检查,规则形同虚设

数据来源与参考

  • Error Prone 官方文档(errorprone.info)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌