如何通过工具提高代码质量:从本地检查到 PR 审查

前言

在学习阶段,我一般不会刻意注意代码规范或潜在漏洞。毕竟代码不正式上线,也没有人专门做审查,很多问题只要“能跑”就被我放过去了。

但现在既然开始做正式项目,就不能再只看功能是否实现。代码能运行只是第一步,后面还要考虑:它是否容易维护、有没有明显缺陷、提交后会不会破坏原有功能,以及团队成员能不能快速看懂。

最近我了解并试用了几种代码质量工具,这里分享给大家。

先说结论:不同工具解决不同问题

工具 主要作用 适用
SpotBugs 发现 Java 字节码中的潜在 Bug IDEA、本地构建、CI
Checkstyle 检查命名、缩进、导入顺序等代码规范 IDEA、本地构建、CI
CodeRabbit 对 Pull Request 做 AI 辅助审查 GitHub PR
reviewdog 把各种检查结果统一评论到代码变更上 GitHub Actions 等 CI

这四个工具的作用领域不同:

  • SpotBugs 更关心“代码可能有问题”;
  • Checkstyle 更关心“代码是否符合团队规范”;
  • CodeRabbit 更接近自动化的代码审查助手;
  • reviewdog 本身通常不负责分析代码,而是负责收集其他工具的输出,并把问题准确标到 PR 对应行上。

SpotBugs:发现潜在 Bug

SpotBugs 是 FindBugs 的后继项目。它会分析 Java 编译后的字节码,寻找空指针、错误的对象比较、资源未关闭、可变对象暴露等潜在问题。

它既有 IDEA 插件,也支持 Maven、Gradle 和 CI。对我来说,IDEA 插件适合在本地快速查看,Maven 插件更适合放进项目流程,避免出现“我的电脑装了插件,但其他人没有装”的情况。

运行完成后,下方会按类型展示检查结果:

选择具体问题后,可以查看对应代码、问题分类和解释:

{spotbugs-detail.png}

spotbugs-detail.png

Maven 配置

下面给出一个比较基础的配置。插件版本建议统一放在项目的 properties 或父 POM 中管理,不要每个模块各写一份。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<configuration>
<effort>Max</effort>
<threshold>Medium</threshold>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>

执行命令:

1
mvn spotbugs:check

需要注意的是,SpotBugs 报告的是“可疑模式”,不代表每一条都一定是 Bug。正确的处理方式是先理解提示,再决定修改、抑制还是调整规则,而不是看到警告就机械改代码。

Checkstyle:统一代码规范

Checkstyle 主要检查代码风格,例如命名、格式、缩进、导入顺序、代码块写法等。

它不会判断业务逻辑是否正确,但可以减少大量没有意义的格式争论。特别是在多人协作时,最好把规范写成配置文件并提交到仓库,而不是只依赖每个人 IDE 里的个人设置。

IDEA 中使用

安装 Checkstyle 插件后,可以进入:

1
2
3
Settings
-> Tools
-> Checkstyle

我这里选择了内置的 Google Checks。点击 Apply 后,可以对单个 Java 文件、目录或整个项目执行检查。

例如下面这段结果,就是在提示等号和花括号附近缺少空格:

1
2
3
4
5
6
Running style checker on 1 file(s) (config: fa26)...
ProductAdminUpdate.java:8:20: '=' 前应有空格。
ProductAdminUpdate.java:8:20: '=' 后应有空格。
ProductAdminUpdate.java:10:3: '{' 后应有空格。
ProductAdminUpdate.java:10:4: '}' 前应有空格。
Style checker completed with 4 errors.

Maven 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>

执行命令:

1
mvn checkstyle:check

如果团队准备长期使用,建议从现有代码能够接受的规则开始,再逐步收紧。直接套一份特别严格的规则,往往会一下出现几千条历史问题,最后大家只能选择关闭检查。

CodeRabbit:辅助审查 Pull Request

CodeRabbit 的定位和前两个工具不太一样。它主要接入 GitHub 等代码托管平台,在 Pull Request 创建或更新后分析变更,并给出摘要、逐行建议和潜在问题。

我认为它比较适合发现下面这些问题:

  • 修改范围较大,人工审查容易漏看;
  • 代码能够编译,但边界条件没有处理;
  • 方法命名、异常处理或重复逻辑不够合理;
  • PR 描述不完整,需要先快速了解本次改动。

不过 AI 审查只能作为辅助,不能代替开发者负责。它不了解全部业务背景,也可能给出看似合理但并不适合当前项目的建议。最终是否修改,仍然要结合需求、测试和上下文判断。

reviewdog:把检查结果送到 PR

reviewdog 是我在 GitHub 的 Code Quality 分类中较早发现的项目。

我一开始以为它也是一个代码检查器,后来才发现它更像一个“结果转发器”:Checkstyle、静态分析器或 Linter 负责发现问题,reviewdog 负责读取这些工具的输出,再把问题作为 PR 评论或检查结果展示出来。

例如可以在 CI 中执行 Checkstyle,再把结果交给 reviewdog。这样开发者不必翻完整日志,就能直接在改动行附近看到提示。

它的价值主要有两点:

  1. 统一不同检查工具的展示方式;
  2. 只关注本次代码变更,避免历史问题淹没新的问题。

我目前推荐的组合

如果是一个普通 Java 项目,我会按下面的顺序接入:

  1. IDE 阶段:使用 Checkstyle 和 SpotBugs 插件,尽量在提交前解决问题;
  2. Maven 阶段:把规则写入 pom.xml,保证任何人执行构建都使用同一套标准;
  3. CI 阶段:运行测试、Checkstyle 和 SpotBugs,不通过就阻止合并;
  4. PR 阶段:根据项目情况接入 CodeRabbit,或用 reviewdog 展示已有工具的结果;
  5. 人工审查:检查业务逻辑、架构影响和需求是否真正实现。

工具链不宜一次堆得太满。先解决项目当前最明显的问题,再逐步增加规则,比安装一堆工具却没有人看结果更有效。