对比和使用了这么多反编译工具,目前觉得 procyon-decompiler 最好用。
官方资料
特点
Procyon Decompiler 尤其擅长反编译以下工作:
- 枚举类声明。
- 枚举和字符串的
switch声明。 - 内部类
- 注解
- Lambda 表达式
输出
Procyon Decompiler 支持三种反编译输出格式:
- Java 代码
- 字节码(相当于 javap)
- 字节码抽象语法树,介于 Java 代码与字节码的中间表示。
使用
运行环境
- JDK1.7 及以上。
语法
java -jar procyon-decompiler.jar <main class> [options] <type names or class/jar files>
示例:
PS C:/> java -jar "C:\Program Files\Jars\procyon-decompiler.jar" java.lang.Object
//
// Decompiled by Procyon v0.6-prerelease
//
package java.lang;
import jdk.internal.HotSpotIntrinsicCandidate;
public class Object
{
private static native void registerNatives();
@HotSpotIntrinsicCandidate
public Object() {}
@HotSpotIntrinsicCandidate
public final native Class<?> getClass();
@HotSpotIntrinsicCandidate
public native int hashCode();
public boolean equals(final Object o) {return this == o;}
@HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
}
@HotSpotIntrinsicCandidate
public final native void notify();
@HotSpotIntrinsicCandidate
public final native void notifyAll();
public final native void wait(final long p0) throws InterruptedException;
public final void wait(long n, final int n2) throws InterruptedException {
if (n < 0L) {
throw new IllegalArgumentException("timeout value is negative");
}
if (n2 < 0 || n2 > 999999) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (n2 > 0) {
++n;
}
this.wait(n);
}
public final void wait() throws InterruptedException {this.wait(0L);}
@Deprecated(since = "9")
protected void finalize() throws Throwable {}
static {registerNatives();}
}
参数
帮助:java -jar procyon-decompiler.jar -?
| opt | full option name | 描述 | |
|---|---|---|---|
-b | --bytecode-ast | 输出字节码抽象语法树 | |
-ci | --collapse-import | 合并 import 列表中同一个包的类 | |
--compiler-target n | 指定反编译的目标 JDK 版本,如 8、9 | ||
-cp | --constant-pool | 输出常量池,仅 -r 时可用,-v 时自动启用 | |
-dl | --debug-line-numbers | 【仍不清楚】 | |
--disable-foreach | 禁用 for each 循环 | ||
-eml | --eager-method-loading | 【仍不清楚】 | |
-ent | --exclude-nested | 不输出内部类 | |
-eta | --explicit-type-arguments | 输出泛型方法的完整参数 | |
-fsb | --flatten-switch-blocks | 去掉 switch 判断中的括号 | |
-fq | --force-qualified-references | 强制输出所有类型的完整全限定名 | |
-lc | --light | 输出控制台定义的白色背景颜色 | |
-lv | --local-variables | 输出本地变量表,仅 -r 时可用,-v 时自动启用 | |
-ll | --log-level n | 设置日志级别(0-3),0 为不显示,默认 0 | |
-ln | --with-line-numbers | 输出行号 | |
-mv | --merge-variables | 合并变量减少声明次数,但可读性会变差 | |
-o | --output-directory dir | 将反编译结果输出到文件夹中 | |
-r | --raw-bytecode | 输出原始字节码,通过 -cp、-lv、-ta、-v 设置输出级别 | |
-ec | --retain-explicit-casts | 保留没有必要的类型转换 | |
-ps | --retain-pointless-switches | 【仍不清楚】 | |
-ss | --show-synthetic | 保留编译器生成的代码,如默认构造方法 | |
-sm | --simplify-member-references | 简化指定类型的成员引用 | |
-sl | --stretch-lines | 【仍不清楚】 | |
--text-block-line-min | 【仍不清楚】 | ||
-ta | --type-attributes | 详细输出对象类型的属性,仅 -r 时可用,-v 时自动启用 | |
--unicode | 以 Unicode 格式输出 | ||
-u | --unoptimized | 显示优化输出之前的代码 | |
-v | --verbose | 详细模式,输出所有信息 | |
--version | 输出 procyon 的版本 |
设置为 IDEA 工具
Setting > Tools >> External Tools >>> + 即可设置为 IDEA 工具,在 Project 的文件上右键可以选择对目标文件执行该命令。
设置:
-
Program:设置为 Java 程序的路径。
-
Arguments:设置 Java 的参数,基础参数为
-jar <procyon-decompiler.jar filepath> $FilePath$。-jar 后接 procyon 的 jar 包路径。
$FilePath$是 IDEA 注入的变量,有非常多,点击+号可以选择自己想用的变量。后面可以接各种 procyon 的参数,根据自己想要的输出形式设置。 -
Working derectory:没用,因为 procyon 不会默认输出文件。
如果希望输出的样式多一点,可以设置成多个工具,如: