拿到一个陌生的 jar 包想看看里面怎么实现的,你第一个反应是什么?JD-GUI?IDEA 自带反编译?还是粘到在线工具?
这篇文章把目前主流的 4 种反编译方式做了实机对比——覆盖 Java 8 到 Java 21 的字节码、Lambda / Records / Switch Expression 等新语法、混淆处理 和 匿名内部类,告诉你什么场景用什么工具。
反编译的本质
编译是 .java → .class(字节码),反编译是 .class → .java(源码近似)。反编译出来的代码永远是近似:
- 变量名丢失(
javac -g:vars能保留,但生产 jar 默认不带) - 注释完全丢失(编译时被丢弃)
- 局部变量类型丢失(可能变成
Object) - 某些语法糖还原不了(如
assert、foreach循环)
所以反编译工具拼的就是:还原度有多高、新语法支持有多快、混淆处理多强。
四种工具实机对比
工具 1:JD-GUI(桌面软件)
老牌反编译工具,打开 jar 直接能看。优点:零配置、速度快、支持导出源码包。缺点:Java 16+ 的新语法(records、sealed classes)还原度差,混淆处理弱。
适用场景:快速扫一眼 jar 结构、看简单类的方法签名。
工具 2:IDEA 自带反编译(JetBrains Decompiler)
IDEA 2017+ 内置,打开 class 文件自动触发。优点:和 IDE 无缝集成、能跳转引用、和本地源码联动。缺点:功能有限(不能一键导出整个 jar、对混淆无能为力),需要有 IDEA 环境。
适用场景:调试时想看依赖 jar 某个类的实现细节。
工具 3:CFR(开源,命令行)
目前还原度最高的开源反编译器之一,持续更新。支持 Java 8-21 的新语法、匿名类、Lambda、Records、Switch Expression。优点:还原度最高、混淆处理强、可作为库嵌入自己的工具。缺点:命令行学习成本、不如 GUI 直观。
java -jar cfr.jar MyClass.class --outputdir ./src
工具 4:在线反编译(本项目工具)
Java 在线反编译 把单个 .class 文件粘到浏览器里直接出源码,结果可复制或下载为 .java。优点:零安装、浏览器即开即用、无需 JDK 环境,底层用 CFR 引擎,还原度和命令行一致。缺点:线上版保持轻量,只支持单个 class(最大 1MB)——整包 jar 解析适合放到本地离线处理,规划在本地工具箱(DXTool 桌面版)中提供。现阶段需先用 jar xf 解压再逐个上传;混淆重的 class 还原后变量名不可读。
还原度测试
| 语法特性 | JD-GUI(典型表现) | IDEA 自带(典型表现) | CFR / 在线(典型表现) |
|---|---|---|---|
| Java 8 Lambda | ✅ | ✅ | ✅ |
| Java 9 Module 系统 | ❌ | ⚠️ | ✅ |
| Java 14 Records | ❌ | ⚠️ | ✅ |
| Java 14 Switch Expression | ❌ | ⚠️ | ✅ |
| Java 17 Sealed Class | ❌ | ❌ | ✅ |
| 匿名内部类 | ✅ | ✅ | ✅ |
| 匿名类里的 this | ❌(变量名错) | ⚠️ | ✅ |
| 混淆处理 | ⚠️(反混淆弱) | ⚠️ | ✅(容错强,变量名仍需 mapping 还原) |
| 局部变量名保留 | ❌ | ❌ | ❌(需要 -g:vars 编译) |
表中为各工具在常见版本上的典型表现(❌ 表示不支持或还原明显出错、⚠️ 表示支持但不完整),并非逐版本实测结论;换用具体版本时以实际输出为准。
选择建议
- 快速扫一眼:IDEA 自带反编译 或 在线反编译(单 class)
- 需要源码包:CFR 命令行 或 在线工具下载 .java 文件
- 混淆重的 jar:CFR 对混淆字节码容错较好,但变量名仍是 a/b/c,需配合 ProGuard/R8 的 mapping 文件人工对照
- 跨语言字节码(Kotlin / Scala):CFR 支持基础还原,需要对应语言的反编译插件
反编译出来的代码能直接用吗?
不能,原因:
- 变量名丢失(反编译成
a、b、c或var) - 注释全丢
- 某些局部变量类型丢失变成
Object - Kotlin 的
data class、suspend fun等特性还原后不是 Kotlin 代码
能参考,用于看实现逻辑、找依赖、排查版本差异。不能直接拿去当源码提交。
相关工具
- Java 在线反编译:CFR 引擎,支持 Java 8-21,匿名类/Lambda/Records/Switch Expression 还原
- Java 转 TypeScript:反编译出的 Java 类一键转 TypeScript interface,用于前后端接口定义对齐