LEEDOM

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

这带来了两个问题:

  1. 路径太长:如果不写全路径,就必须 cd 到 JAR 包所在的目录。
  2. 参数被淹没:当你要加上各种参数(如指定输出目录、引入依赖包)时,整条命令会变得极其冗长,极易拼错。
    我们的目标是将其简化为:
1
cfr target/MyClass.class --outputdir ./src

实战:如何配置全局环境变量(Windows & macOS/Linux)

配置全局环境变量的核心思想是:将 JAR 包固定在一个目录,写一个启动脚本,然后把脚本目录加入到系统的 PATH 变量中。

准备工作

  1. 前往 CFR 官网 下载最新版的 .jar 文件(例如 cfr-0.152.jar)。
  2. 将其放到一个你绝对不会误删的固定目录:
    • Windows 示例C:\tools\cfr\
    • macOS/Linux 示例/usr/local/cfr/~/tools/cfr/

1. Windows 系统配置

第一步:创建启动脚本
C:\tools\cfr\ 目录下,新建一个文本文件,重命名为 cfr.bat(注意后缀必须是 .bat),写入以下内容:

1
2
3
@echo off
set CFR_HOME=C:\tools\cfr
java -jar "%CFR_HOME%\cfr-0.152.jar" %*

(注:%* 的作用是接收你在命令行输入的所有参数并原样传递给 JAR 包)
第二步:添加环境变量

  1. 右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”。
  2. 在“系统变量”(或“用户变量”)中找到 Path,点击“编辑” -> “新建”。
  3. 添加路径:C:\tools\cfr,一路点击“确定”保存。
    验证:
    打开一个新的 CMD 或 PowerShell 窗口,输入 cfr --version,如果能看到版本信息,恭喜你配置成功!

2. macOS / Linux 系统配置

第一步:创建启动脚本
打开终端,使用 vim 或 nano 创建一个没有后缀的脚本文件:

1
sudo vim /usr/local/bin/cfr

写入以下内容并保存:

1
2
3
#!/usr/bin/env bash
CFR_HOME=/usr/local/cfr
exec java -jar "$CFR_HOME/cfr-0.152.jar" "$@"

第二步:赋予执行权限

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 表达式,而是能看到底层真实的 invokedynamicLambdaMetafactory 调用链。
  • --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
2
3
4
# Mac/Linux
cfr complex-app.jar --outputdir ./src --extraclasspath "lib/*" --decodelambdas false
# Windows
cfr complex-app.jar --outputdir ./src --extraclasspath "lib\*" --decodelambdas false

总结
CFR 是一款非常轻量且强悍的工具。通过简单地写一个几行代码的脚本并配置 PATH,我们彻底告别了冗长的 java -jar 命令。再搭配上 --extraclasspath 和几个语法糖开关,足以应付工作学习中 99% 的反编译需求。
如果你还没有用过 CFR,强烈建议去 官网 下载下来试试,它一定会成为你 Java 工具箱里不可或缺的一把瑞士军刀!

OLDER >