ARTICLE · 1122788
这5个非常厉害的 IDEA 插件,可以当作代码的质量检查工具!

做开发这些年,代码写得越多越会发现:很多低级问题,自己盯着看就是看不出来。人工评审又慢又容易走过场,于是这类机械检查,我基本都丢给了 IDEA 插件。今天先给大家推荐 5 款我自己经常用的牛逼插件。

线上的 NPE 在最后被定位到了一行 user.getAddress().getCity()
User 是上层接口返回的数据,可以为空。这一行可以被编译,并且在单独测试的时候也可以运行通过,但是当真正的流量到来时就会爆炸。如果当时挂了 SpotBugs 的话,在提交之前就已经是红色了。
静态检查并不是装上一些插件来求个心安,而要明白每一个工具所要分析的内容是什么。
阿里规约:底层其实就是 PMD
它不是单独的一个引擎,在实际工作中用到的是开源项目 P3C 中的 p3c-pmd 模块,一套运行在 PMD 上的规则集合。把《阿里巴巴 Java 开发手册》中 54 条可以自动化的规则拆分成 10 个小规则集。插件就是个外壳,规则内核可以直接挂到构建流程中去。
规则分为 Blocker、Critical、Major 3 个等级。Executors.newFixedThreadPool() 会成为 Blocker,因为它默认使用的是无界队列,并且任务堆积在一起就会把内存撑爆。它的价值就在于把“应该不应该这样写”这样的扯不清楚的事情变成一条可以进入 CI 的规则。
CheckStyle 并不是只有检查格式的功能
说它是只管格式不讲对错,只说对了一半。它的工作层次为源码层,除了缩进命名之外,还有许多设计度量规则:CyclomaticComplexity 卡圈复杂度、MethodLength 卡方法长度、ParameterNumber 卡参数个数、ClassDataAbstractionCoupling 卡一个类有多少个外部类被它所依赖。不是说好还是不好看的问题,而是说一个方法之后能不能再修改。
自带的 sun_checks.xml 严格到了可以发现正常的项目的几千个问题,用 google_checks.xml 作为基础,另外还要有一个 suppressions.xml 文件按照路径来豁免才能用到。
PMD:AST+XPath 可以自己编写规则
PMD 对源代码进行解析后得到的是抽象语法树(AST)。每一个规则都相当于对一棵树做一次查询。CloseResource 检查资源是否已经关闭、UnusedPrivateField 检查是否有未使用的私有字段、EmptyCatchBlock 检查是否有空的 catch 块,都依靠着它,而且它可以直接使用 XPath 来编写规则,例如 //ClassOrInterfaceDeclaration[@SimpleName='Foo'] 可以锁定一个类的名字,不需要进行 Java 编译工作。
PMD 默认不进行类型解析,CloseResource 这样的规则没有配置到 auxClasspath 中就会出现误报和漏报的情况。同项目的 CPD(复制粘贴检测器),按照 token 来查找跨文件的重复块,--minimum-tokens 100 这个阈值自己设定。重复代码最恶心的并不是它的丑陋,而是当你修改了其中的一处之后又忘记了另外一处。
SpotBugs:读字节码,看到的是源码看不到的东西
其中只有它不看源代码,而是直接阅读编译之后的 .class 文件,并且使用数据流分析来实现跨方法追踪变量的取值路径。400 多个检测器,每个都带有编号:NP_NULL_ON_SOME_PATH 空指针、ES_COMPARING_STRINGS_WITH_EQ 字符串用 == 比、OS_OPEN_STREAM 流开了没关、RV_RETURN_VALUE_IGNORED 忽略了有意义的返回值、EI_EXPOSE_REP getter 把内部可变集合吐了出去。
// EI_EXPOSE_REP:外部拿到这个list就可以改变你内部的状态public List<String> getItems() { return items; }另外一点是 FindBugs 从 2015 年开始就不更新了,接替它的 SpotBugs 才有了新的规则,并且可以挂上 find-sec-bugs 进行安全检测。它的速度比较慢,不要用编辑器来运行它,在构建阶段运行。
SonarLint:和服务器端使用同一个引擎
底层是 SonarQube 中使用的 sonar-java 引擎,并且规则使用 S 编号。打开 Connected Mode 连接到服务器,本地 Quality Profile 和服务器端完全一样,就不会出现本地一片绿色、流水线上全是红色的情况。经常出现的 S2259 空指针、S3776 认知复杂度、S1192 字符串重复等问题都会被一键修复。在编辑器中经常使用的只有它一个。
这五种并不是平行排列的,要按照反馈的速度来分类
它们的功能重叠很多:阿里巴巴规范的基础就是 PMD,SonarLint 里面也有很多和 PMD、CheckStyle 撞车的规则。把所有选项都打到最大值,同样的一个问题重复出现 5 次以上,再加上一些错误的报警信息,人们很快就会变得麻木不仁,插件也就成了多余之物。
我所采用的方法是在编辑器中仅保留 SonarLint 和阿里规范,并且毫秒级地进行标红,在写的时候就马上开始修改;在提交之前要进行 CheckStyle 检查;到 CI 再上 PMD、CPD、SpotBugs 进行深入分析,速度没有问题。
机器可以对一些能定性的问题进行拦截,在提交之前,人的审查精力就可以全部投入到对架构是否合理、边界情况有没有考虑周全等问题的关注中去
这部分,机器一时半会儿也抢不走。