前言

JAD 是一款老牌的、经典的、能够让你了解 Java 编译器真实工作原理的 Java 反编译工具。

大家都知道,将源代码转换成二进制执行代码的过程叫“编译”,比如将 Java 源代码编译成 .class 字节码文件,那么把字节码文件转换成代码的过程就叫“反编译”。

JAD 镜像下载网站:https://varaneckas.com/jad/

JAD 的官网:http://www.kpdus.com/jad.html,官网的 JAD 文件已经下不了了。

这里提供 Mac OS 和 Windows 的 JAD 文件:

接下来介绍 Windows 环境 JAD 的安装和使用。

正文

先将 JAD 压缩文件下载到本地,解压后,看到如下两个文件:

  • jad.exe(无法直接运行)
  • Readme.txt(使用说明)

注意一下,jad.ext 文件不能直接运行,双击是没有反应的,需要继续执行下面的步骤。

配置环境变量

为了更便捷的使用 jad,我们可以将其加入到环境变量中。

新建 JAD_HOME 环境变量:
image.png
加入到 PATH 中:
image.png

使用方法

假如有这样一段代码:

  1. package test11;
  2. public class Test9 {
  3. public static void main(String[] args) {
  4. String message = "User's age: ";
  5. int age = 18;
  6. System.out.println(message + age);
  7. }
  8. }

保存后的文件名为 Test9.java,打开 CMD,进入该文件所在的路径,先使用 javac 进行编译,生成 .class 文件。

然后输入如下命令,使用 JAD 反编译 .class 文件。

  1. PS E:\projects\test\target\classes\test11> jad .\Test9.class

如果提示信息如下,则证明反编译成功。

  1. Parsing .\Test9.class... Generating Test9.jad

与此同时,Test9.class 所在的文件夹下会多出来一个新的文件 Test9.jad,用文本编辑器打开即可查看。

  1. // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
  2. // Jad home page: http://www.kpdus.com/jad.html
  3. // Decompiler options: packimports(3)
  4. // Source File Name: Test9.java
  5. package test11;
  6. import java.io.PrintStream;
  7. public class Test9
  8. {
  9. public Test9()
  10. {
  11. }
  12. public static void main(String args[])
  13. {
  14. String message = "User's age: ";
  15. int age = 18;
  16. System.out.println((new StringBuilder()).append(message).append(age).toString());
  17. }
  18. }

和 JD-GUI 的不同之处

需要注意的是:JAD 不是 JD-GUI,两者都是反编译工具,但并不相同。

比如上面这段代码,JD-GUI 反编译后的结果如下所示:
image.png
可以看得出来,JD-GUI 显示的是最原始的 Java 源代码。而 JAD 显示的是更贴近事实的源代码:+ 号操作符在编译的时候其实是会转成 StringBuilder 。

这特别的关键,如果你想知道编译器后的真实内容就使用 JAD。就像 javap 一样,只不过更加的清晰明了,javap 一般人看不太懂,如下:

  1. PS E:\projects\test\target\classes\test11> javap -c .\Test9.class
  2. Compiled from "Test9.java"
  3. public class test11.Test9 {
  4. public test11.Test9();
  5. Code:
  6. 0: aload_0
  7. 1: invokespecial #1 // Method java/lang/Object."<init>":()V
  8. 4: return
  9. public static void main(java.lang.String[]);
  10. Code:
  11. 0: ldc #2 // String User's age:
  12. 2: astore_1
  13. 3: bipush 18
  14. 5: istore_2
  15. 6: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
  16. 9: new #4 // class java/lang/StringBuilder
  17. 12: dup
  18. 13: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
  19. 16: aload_1
  20. 17: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  21. 20: iload_2
  22. 21: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  23. 24: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  24. 27: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
  25. 30: return
  26. }

转载

反编译工具 JAD:让你了解Java编译器的真实工作原理

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/anv3ce 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。