Apr 11, 2026
CFR Java反编译器全局配置与常用参数指南
原文链接/官方网址: https://www.benf.org/other/cfr/
在 Java 开发中,排查线上问题或者研究第三方库时,我们经常需要进行反编译。在众多工具中,CFR 无疑是现代 Java 开发者的首选之一。它不仅开源、单文件零依赖,而且对 Java 8 以后的 Lambda 表达式、Switch 字符串、方法引用等新特性支持得极其出色。
但是,每次反编译都要输入一长串 java -jar cfr-0.152.jar xxx.class,是不是觉得特别繁琐?
今天这篇博客,我们就来彻底解决这个痛点:手把手教你为 CFR 配置全局环境变量,并整理一份最实用的常用参数速查表,让你像使用原生命令一样优雅地使用 CFR。
痛点:为什么要配置全局命令?
默认情况下,我们使用 CFR 是这样的:
1 | java -jar /path/to/your/directory/cfr-0.152.jar target/MyClass.class |
这带来了两个问题:
- 路径太长:如果不写全路径,就必须
cd到 JAR 包所在的目录。 - 参数被淹没:当你要加上各种参数(如指定输出目录、引入依赖包)时,整条命令会变得极其冗长,极易拼错。
我们的目标是将其简化为:
1 | cfr target/MyClass.class --outputdir ./src |
实战:如何配置全局环境变量(Windows & macOS/Linux)
配置全局环境变量的核心思想是:将 JAR 包固定在一个目录,写一个启动脚本,然后把脚本目录加入到系统的 PATH 变量中。
准备工作
- 前往 CFR 官网 下载最新版的
.jar文件(例如cfr-0.152.jar)。 - 将其放到一个你绝对不会误删的固定目录:
- Windows 示例:
C:\tools\cfr\ - macOS/Linux 示例:
/usr/local/cfr/或~/tools/cfr/
- Windows 示例:
1. Windows 系统配置
第一步:创建启动脚本
在 C:\tools\cfr\ 目录下,新建一个文本文件,重命名为 cfr.bat(注意后缀必须是 .bat),写入以下内容:
1 | @echo off |
(注:%* 的作用是接收你在命令行输入的所有参数并原样传递给 JAR 包)
第二步:添加环境变量
- 右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
- 在“系统变量”(或“用户变量”)中找到
Path,点击“编辑” -> “新建”。 - 添加路径:
C:\tools\cfr,一路点击“确定”保存。
验证:
打开一个新的 CMD 或 PowerShell 窗口,输入cfr --version,如果能看到版本信息,恭喜你配置成功!
2. macOS / Linux 系统配置
第一步:创建启动脚本
打开终端,使用 vim 或 nano 创建一个没有后缀的脚本文件:
1 | sudo vim /usr/local/bin/cfr |
写入以下内容并保存:
1 |
|
第二步:赋予执行权限
1 | sudo chmod +x /usr/local/bin/cfr |
(注:通常 /usr/local/bin 已经在你的 PATH 中了,无需额外配置)
验证:
新开一个终端窗口,输入 cfr --help,看到参数列表即大功告成。
进阶:CFR 常用参数详解与实战
配置好全局命令后,我们就该玩转 CFR 的参数了。CFR 的参数非常多,但日常开发中 80% 的场景只用掌握以下几个:
💡 提示:随时可以在终端输入
cfr --help查看当前版本支持的所有参数及默认值。
1. 基础输出控制
- 默认行为:如果不加任何输出参数,CFR 会将反编译后的 Java 代码直接打印在控制台里。
--outputdir <目录>:将反编译后的.java文件输出到指定目录(最常用)。1
2# 将 app.jar 反编译并保存到当前目录的 src 文件夹下
cfr app.jar --outputdir ./src
2. 解决依赖报错(核心痛点)
反编译时经常会遇到 Couldn't load class XXX 的报错,因为被反编译的类引用了第三方库。注意:使用 java -jar 运行时,标准的 -cp 参数是无效的!
--extraclasspath <路径>:指定额外的类路径(JAR 包或 class 目录),多个路径用系统分隔符隔开(Windows 用;,Mac/Linux 用:)。1
2
3
4
5# Windows 示例:引入 lib 目录下的两个依赖包
cfr my-app.jar --outputdir ./src --extraclasspath "lib/fastjson.jar;lib/commons-lang3.jar"
# Mac/Linux 示例:引入当前目录下所有 jar
cfr my-app.jar --outputdir ./src --extraclasspath "lib/*"
3. 语法糖开关(探究底层实现的神器)
CFR 最强大的地方在于它能“完美还原”各种语法糖,但如果你是一个喜欢研究底层字节码原理的极客,你可以手动关闭这些还原:
--sugarenums false(默认 true):关闭枚举的语法糖还原。--decodelambdas false(默认 true):非常实用! 关闭后,你将看不到 Lambda 表达式,而是能看到底层真实的invokedynamic和LambdaMetafactory调用链。--sugarboxing false(默认 true):关闭自动装箱/拆箱还原。--decodestringswitch false(默认 true):关闭字符串 Switch 还原。
实战场景:想看看 Lambda 到底被编译成了什么样?
1 | cfr StreamDemo.class --decodelambdas false |
4. 匿名类与内部类处理
--removeboilerplate false(默认 true):默认情况下,CFR 会移除一些为了支持内部类而生成的“模板代码”(如传递给内部类的this$0参数)。如果你想看最原始的结构,设为 false。--aexagg false(默认 true):关闭对异常块的过度展开(有时候反编译出来的 try-catch 代码块比较怪异,关闭此选项可改善)。
老司机的“抄作业”速查表
最后,整理了三个我日常工作中最常用的命令模板,大家可以按需复制:
场景一:快速查看某个 Class 的代码(不求保存)
1 | cfr target/classes/com/example/UserService.class |
场景二:反编译整个 Spring Boot JAR 包并保存
1 | cfr demo-0.0.1-SNAPSHOT.jar --outputdir ./decompiled-sources |
场景三:反编译带有复杂依赖的 JAR,并保留底层 Lambda 实现细节
1 | # Mac/Linux |
总结
CFR 是一款非常轻量且强悍的工具。通过简单地写一个几行代码的脚本并配置 PATH,我们彻底告别了冗长的 java -jar 命令。再搭配上 --extraclasspath 和几个语法糖开关,足以应付工作学习中 99% 的反编译需求。
如果你还没有用过 CFR,强烈建议去 官网 下载下来试试,它一定会成为你 Java 工具箱里不可或缺的一把瑞士军刀!