一、jdk自带的javap
使用体验:先执行javac *.java将源代码编译生产class(由于依赖关系,单个java文件编译可能会报错)。
cd到该目录下,javap -c 文件名(不要带.class后缀)即可查看到反编译后的文件内容,类似
public class design.method.proxyPattern.DynamicIntermediar extends java.lang.Object implements java.lang.reflect.InvocationHandler{
public design.method.proxyPattern.DynamicIntermediar();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public java.lang.Object getInstance(java.lang.Object) throws java.lang.Exception;
Code:
0: aload_0
1: aload_1
2: putfield #2; //Field target:Ljava/lang/Object;
5: aload_1
6: invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class;
9: astore_2
10: aload_2
11: invokevirtual #4; //Method java/lang/Class.getClassLoader:()Ljava/lang/ClassLoader;
14: aload_2
15: invokevirtual #5; //Method java/lang/Class.getInterfaces:()[Ljava/lang/Class;
18: aload_0
19: invokestatic #6; //Method java/lang/reflect/Proxy.newProxyInstance:(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;
22: areturn
public java.lang.Object invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) throws java.lang.Throwable;
Code:
0: aload_0
1: invokespecial #7; //Method before:()V
4: aload_2
5: aload_0
6: getfield #2; //Field target:Ljava/lang/Object;
9: aload_3
10: invokevirtual #8; //Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
13: astore 4
15: aload_0
16: invokespecial #9; //Method after:()V
19: aload 4
21: areturn
public static void main(java.lang.String[]);
Code:
0: new #14; //class design/method/proxyPattern/DynamicIntermediar
3: dup
4: invokespecial #15; //Method "<init>":()V
7: new #16; //class design/method/proxyPattern/Customer
10: dup
11: invokespecial #17; //Method design/method/proxyPattern/Customer."<init>":()V
14: invokevirtual #18; //Method getInstance:(Ljava/lang/Object;)Ljava/lang/Object;
17: checkcast #19; //class design/method/proxyPattern/Person
20: astore_1
21: aload_1
22: invokeinterface #20, 1; //InterfaceMethod design/method/proxyPattern/Person.findHouse:()V
27: aload_1
28: invokeinterface #21, 1; //InterfaceMethod design/method/proxyPattern/Person.findCar:()V
33: aload_1
34: invokeinterface #22, 1; //InterfaceMethod design/method/proxyPattern/Person.findPartner:()V
39: goto 47
42: astore_1
43: aload_1
44: invokevirtual #24; //Method java/lang/Exception.printStackTrace:()V
47: return
Exception table:
from to target type
0 39 42 Class java/lang/Exception
}
应用javap反编译与源码有差距,但更接近代码操作的实质。
二、jadclipse反编译插件
eclipse插件,挺好用,便于查看源码。
三、直接将class文件拖至IDEA窗口
直接将想查看的class文件拖至IDEA,也可查看源码。
四、jad.exe
下载地址https://varaneckas.com/jad/,下载后解压,cd到jad.exe目录下,jad 指定文件,即可生成反编译文件,默认.jad文件,也可指定直接上传java文件,用命令:jad -o -dtest111 -sjava 指定class。-d指定生成文件的存储路径。
五、jd-gui
使用起来跟普通解压缩工具差不多,可以直接打开jar包并查看jar内所有class文件。
以上是我使用过的反编译方法,如果有更好的方法,后续会继续补充,也欢迎大家补充。