什么是静态分析?
什么是静态分析?
静态分析是指在不执行应用程序的情况下对源代码进行自动化分析。
如果在程序执行期间进行分析,则称为动态分析。
静态分析常用于检测:
- 安全漏洞。
- 性能问题。
- 不符合标准。
- 使用过时的编程结构。
静态分析工具是如何工作的?
所有静态分析工具的共同基本概念是搜索源代码,以识别与某种警告或信息相关联的特定编码模式。
这可能很简单,例如“JUnit 5 测试类不需要是 'public'”。也可能很复杂,例如识别“SQL 执行语句中使用了不受信任的字符串输入”。
静态分析工具实现此功能的方式各不相同。
- 用于创建抽象语法树 (AST) 的源代码解析技术,
- 文本正则表达式匹配,
- 上述两者的结合。
基于文本的正则表达式匹配非常灵活,编写匹配规则也很容易,但往往会导致大量的误报,且匹配规则无法感知周围的代码上下文。
AST 匹配将源代码视为程序代码,而不仅仅是充满文本的文件,这允许进行更具体、更具上下文的匹配,并能减少针对代码报告的误报数量。
持续集成中的静态分析
静态分析通常在持续集成 (CI) 过程中执行,以生成合规性问题报告,通过审查这些报告,可以客观地了解代码库随时间的变化情况。
有些人通过配置静态分析工具来仅测量代码的特定部分并仅报告规则的子集,从而将静态分析作为衡量代码质量的客观标准。
客观性由所使用的规则提供,因为这些规则在评估代码时不会随时间而改变。显然,所用规则的组合及其配置是一个主观决定,不同的团队会在不同时间选择使用不同的规则。
在 CI 中执行静态分析很有用,但可能会延迟给程序员的反馈。程序员在编写代码时无法获得反馈,而是在代码通过静态分析工具运行时才收到反馈。在 CI 中运行静态分析的另一个副作用是结果更容易被忽视。
为了让团队更重视静态分析的结果,通常可以在构建过程中配置阈值指标,一旦指标超标(例如触发的规则数量过多),构建就会失败。
IDE 中的静态分析
为了更快获得反馈,许多 IDE 插件支持按需或在代码变更时定期运行静态分析规则。
程序员在编写代码时,可以直接在 IDE 中看到违规提示。为了让这些规则更难被忽视,通常还可以将违规项配置为在编辑器中以代码下划线的形式显示。
我个人认为这是一种提升编码水平的有效方法,尤其是在使用静态分析工具所覆盖的新库时。虽然它可能会因为误报或一些你并不关心的规则而显得有些“嘈杂”,但通过额外配置静态分析工具来忽略特定规则,就能解决这个问题。
基于静态分析规则修复代码
对于大多数静态分析工具,规则修复工作由程序员自行完成,因此他们必须理解违规原因并掌握修复方法。
极少数静态分析工具具备自动修复违规的能力,因为修复方案往往高度依赖于团队、所用技术栈以及约定的编码风格。
默认规则
当静态分析工具自带默认规则时,人们容易对规则的质量产生盲目自信,误以为它们涵盖了程序员可能遇到的所有问题及所有适用场景。然而,规则的适用条件有时非常微妙,并不容易被察觉。
我们希望通过使用静态分析工具,并深入研究规则和违规项,程序员能够培养出在特定领域背景下识别并规避问题的能力。
当业务领域需要特定上下文规则时,静态分析工具可能无法提供匹配的规则,此外,这些工具往往难以配置和扩展。
困扰
这些“困扰”并非无法克服:
- 误报
- 缺乏自动修复
- 需要配置以忽略规则
- 添加特定上下文规则
但它们常被用作拒绝使用静态分析工具的借口,这很可惜,因为静态分析在以下方面极具价值:
- 向初级开发人员展示更好的编程方法
- 针对明显的编码违规快速获得反馈
- 识别程序员从未遇到过的隐蔽问题
- 确认程序员采用了良好的编码方式(当未报告任何违规时)
基于 IDE 的静态分析工具
作为项目的个人贡献者,我喜欢使用在 IDE 内运行的静态分析工具,以便快速获得代码反馈。
这可以作为项目现有的拉取请求(Pull Request)审查流程和持续集成(CI)的有效补充。
我一直在寻找能让我如虎添翼的工具,以优化个人的工作流程。
当工具在 IDE 中运行时,由于它们往往采用相似的基础图形界面和配置方式,人们很容易误以为它们是可以互换的。
这些工具的功能或规则集或许会有重叠,但为了发挥最大效用,我会同时安装多种工具,以 博采众长。
以下是我在编码时经常使用的静态分析 IDE 工具:
- IntelliJ 内置检查功能 - 常见编码模式
- SpotBugs - 常见错误
- SonarLint - 常见用法模式
- CheckStyle - 常见风格模式
- Secure Code Warrior 的 Sensei - 自定义规则创建
我之所以全部使用它们,是因为它们能够相辅相成,互为补充。
IntelliJ 检查
如果你使用 IntelliJ,那么你其实已经在用它的检查功能了。
这些是 IDE 中标记出的静态分析规则。其中一些还提供“快速修复”(QuickFix)选项,可以直接重写代码以解决问题。
这些规则可以自由开启或关闭,你还可以选择在 IDE 中高亮显示这些问题时所采用的错误级别。

IntelliJ 有许多优秀的检查功能。我在撰写本文时特意查阅了一番,对此深有体会。我通常直接使用 IntelliJ 的默认检查设置,并未进行额外配置。但为了充分发挥这些检查工具的价值,建议你仔细阅读一遍,找出与你编码风格相关的规则,并调整警告级别,以便在代码中及时发现问题。
IntelliJ 检查功能的一大优势在于它随 IDE 免费提供,且有助于培养以下肌肉记忆:
- 在编写代码时即时注意到源码中的警告和错误
- 将鼠标悬停在被标记的代码上,了解违反了哪些规则
- 使用 alt+enter 快捷键应用“快速修复”来解决问题

SpotBugs
这款 SpotBugs IntelliJ 插件利用静态分析技术,旨在提醒你代码中潜在的 Bug。
你可以在 IntelliJ 的首选项中配置 SpotBugs 来扫描代码,具体的规则可以在“检测器”(Detector)选项卡中查看。

我通常会在写完并检查完代码后使用 SpotBugs,然后运行“分析项目文件(包括测试源)”。

这确实能帮我发现 Bug、死代码以及显而易见的优化点。它还促使我去研究一些被标记出的违规项,从而帮助我决定如何处理。
SpotBugs 虽然能发现问题,但不提供任何“快速修复”操作来尝试解决这些问题。
SpotBugs 配置简单,我认为它是 IDE 中一个非常有用的客观“第二意见”。
SonarLint
SonarLint 插件。
您可以在 IntelliJ 的首选项中配置 SonarLint,以选择用于验证代码的规则。

默认情况下,SonarLint 会实时运行,并显示您当前正在编辑的代码中存在的问题。
SonarLint 不提供快速修复功能,但其违规报告附带的文档通常清晰且详尽。
我过去常使用 SonarLint,它能提醒我注意 Java 新版本中我尚未掌握的新特性,这非常有用。
CheckStyle
CheckStyle 插件结合了格式化规则和代码质量规则。
CheckStyle 插件内置了“Sun Checks”和“Google Checks”规则集。
这些规则的定义可以轻松地 在线查阅。
当项目投入时间创建了自定义规则集时,CheckStyle 才能发挥最大价值。配置 IDE 插件以使用该规则集后,程序员可以在提交代码到 CI 之前进行扫描。
CheckStyle 常被用作 CI 流程中的构建失败插件,当 CheckStyle 违规数量超过阈值时,构建即会失败。
Sensei
Sensei 基于抽象语法树 (AST) 进行静态分析,用于匹配代码并创建快速修复 (QuickFix),这使得它能够非常精准地识别代码问题。
AST 使与配方 (recipe) 关联的快速修复能够理解周围的代码。例如,在代码中添加新类时,该类的导入语句只会被添加到源文件中一次,而不会在每次替换时重复添加。
Sensei 的创建旨在简化自定义匹配规则的构建,这些规则在其他工具中可能不存在,或者难以配置。
无需修改配置文件,所有配置均可在图形界面 (GUI) 中完成。在创建新配方时,GUI 可以轻松查看配方匹配的代码。定义快速修复时,还可以立即对比代码修改前后的状态。这使得创建高度情境化的配方变得更加容易,即针对特定团队、技术甚至个人程序员的独特需求进行定制。

我常将 Sensei 与其他静态分析工具结合使用。例如,大多数静态分析工具只能发现问题,却无法修复。Sensei 的一个常见用例是在 Sensei 中复刻其他工具的匹配搜索,并增加快速修复功能。这样做的好处是,所应用的自定义修复方案已经符合您项目的编码标准。
我有时会创建一些 Sensei 配方,而这些配方其实在 IntelliJ 的 Intensions 集中已经存在。这是因为 Intension 报告并不完全符合我所设定的情境,或者 IntelliJ 提供的快速修复方案与我想要使用的代码模式不匹配。
我倾向于增强现有工具的功能,而不是试图完全取代它们。
当您发现通用规则的特定情境变体时,Sensei 也非常有用。例如,如果您使用的 SQL 库不受静态分析工具支持,但静态分析引擎中的通用 SQL 规则仍然适用,那么您可以使用 Sensei 为这些规则创建特定于库的变体。
与上述静态分析工具不同,Sensei 开箱即用的通用规则并不多。它的核心优势在于能够轻松创建自定义规则,并配置与您编码风格和应用场景相匹配的快速修复(QuickFix)。
注:我们正在构建一个涵盖通用场景的公共规则库,您可以点击此处查看。
总结
我倾向于选择那些能够协同工作、具备高度可配置性且易于扩展以满足特定需求的工具。多年来,我一直使用 IDE 中的静态分析工具来辅助识别代码问题,并借此深入了解所使用的编程语言和库。
我将上述所有工具结合使用:
- IntelliJ Intentions 开箱即用,可标记常见代码问题,并通常提供相应的快速修复。
- SpotBugs 能发现我可能遗漏的简单错误,并提醒我注意性能问题。
- SonarLint 能识别我未曾注意到的 Java 特性,并引导我以更多方式优化代码建模。
- CheckStyle 帮助我遵循团队约定的编码规范,并在持续集成(CI)过程中强制执行。
- Sensei 则帮助我创建快速修复,以增强静态分析工具发现的常见场景,并针对其他工具难以配置的特定项目或技术需求创建自定义规则。
---
在 IntelliJ 中安装 Sensei:Mac 用户请进入“Preferences \ Plugins”,Windows 用户请进入“Settings \ Plugins”,然后搜索“sensei secure code”即可。
您可以在 Secure Code Warrior 的 GitHub 账号下找到 `sensei-blog-examples` 项目,其中包含了针对常见用例的示例代码和规则库。
https://github.com/securecodewarrior/sensei-blog-examples
在 AI 驱动的开发成果发布前实现有效治理
评估 AI 辅助风险,在提交代码时强制执行安全编码策略,并加速整个软件开发生命周期的安全交付。
探索更多博客
获取有关安全编码、人工智能治理和软件风险管理的专家内容。
%252520%252520(3).avif)
Supercharged Security Awareness: How Tournaments are Inspiring Developers at Erste Group
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse varius enim in eros elementum tristique. Duis cursus, mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam libero vitae erat. Aenean faucibus nibh et justo cursus id rutrum lorem imperdiet. Nunc ut sem vitae risus tristique posuere.

Security as culture: How Blue Prism cultivates world-class secure developers
Learn how Blue Prism, the global leader in intelligent automation for the enterprise, used Secure Code Warrior's agile learning platform to create a security-first culture with their developers, achieve their business goals, and ship secure code at speed
在产品发布前确保 AI 驱动的开发安全
洞察开发风险,执行安全策略,并在整个软件开发生命周期中预防漏洞。



.avif)