在 Java 中,可以使用命令行工具 javap
来反编译 .class
文件。 javap
命令可以查看 .class
文件的字节码,并将其转换为可读的代码。下面是使用 javap
命令反编译一个 .class
文件的步骤:
.class
文件所在的目录。.class
文件:javap -c -p -v MyClass.class
这里的 MyClass
是要反编译的类名,你需要将其替换为你要反编译的类的名称。 -c
选项表示输出字节码指令, -p
选项表示输出类、方法和字段的访问修饰符, -v
选项表示输出类的详细信息,包括常量池、字段信息、方法信息等。
javap
将会输出反编译后的代码。注意:反编译的代码并不一定完全等同于原始代码,因为在编译时会进行一些优化和改变代码结构的操作,因此反编译后的代码可能会略有不同。
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
intList.add(3);
Integer firstElement = intList.get(0);
System.out.println("firstElement: " + firstElement);
}
}
javap -c -p -v Main.class
D:\learn\experiment\Java\learn\my_spring\target\production\my_spring\cn\gd\cz\hong>javap -c -p -v Main.class
Classfile /D:/learn/experiment/Java/learn/my_spring/target/production/my_spring/cn/gd/cz/hong/Main.class
Last modified 2023年3月29日; size 1235 bytes
SHA-256 checksum 32fc69742d2203ed05e00f6e35e34ea35230b90ce57a6ead1dd7c1a3d2cdc3a4
Compiled from "Main.java"
public class cn.gd.cz.hong.Main
minor version: 0
major version: 52
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #17 // cn/gd/cz/hong/Main
super_class: #18 // java/lang/Object
interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
#1 = Methodref #18.#38 // java/lang/Object."":()V
#2 = Fieldref #39.#40 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #41 // Hello world!
#4 = Methodref #42.#43 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #44 // java/util/ArrayList
#6 = Methodref #5.#38 // java/util/ArrayList."":()V
#7 = Methodref #10.#45 // java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
#8 = InterfaceMethodref #46.#47 // java/util/List.add:(Ljava/lang/Object;)Z
#9 = InterfaceMethodref #46.#48 // java/util/List.get:(I)Ljava/lang/Object;
#10 = Class #49 // java/lang/Integer
#11 = Class #50 // java/lang/StringBuilder
#12 = Methodref #11.#38 // java/lang/StringBuilder."":()V
#13 = String #51 // firstElement:
#14 = Methodref #11.#52 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#15 = Methodref #11.#53 // java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
#16 = Methodref #11.#54 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#17 = Class #55 // cn/gd/cz/hong/Main
#18 = Class #56 // java/lang/Object
#19 = Utf8
#20 = Utf8 ()V
#21 = Utf8 Code
#22 = Utf8 LineNumberTable
#23 = Utf8 LocalVariableTable
#24 = Utf8 this
#25 = Utf8 Lcn/gd/cz/hong/Main;
#26 = Utf8 main
#27 = Utf8 ([Ljava/lang/String;)V
#28 = Utf8 args
#29 = Utf8 [Ljava/lang/String;
#30 = Utf8 intList
#31 = Utf8 Ljava/util/List;
#32 = Utf8 firstElement
#33 = Utf8 Ljava/lang/Integer;
#34 = Utf8 LocalVariableTypeTable
#35 = Utf8 Ljava/util/List;
#36 = Utf8 SourceFile
#37 = Utf8 Main.java
#38 = NameAndType #19:#20 // "":()V
#39 = Class #57 // java/lang/System
#40 = NameAndType #58:#59 // out:Ljava/io/PrintStream;
#41 = Utf8 Hello world!
#42 = Class #60 // java/io/PrintStream
#43 = NameAndType #61:#62 // println:(Ljava/lang/String;)V
#44 = Utf8 java/util/ArrayList
#45 = NameAndType #63:#64 // valueOf:(I)Ljava/lang/Integer;
#46 = Class #65 // java/util/List
#47 = NameAndType #66:#67 // add:(Ljava/lang/Object;)Z
#48 = NameAndType #68:#69 // get:(I)Ljava/lang/Object;
#49 = Utf8 java/lang/Integer
#50 = Utf8 java/lang/StringBuilder
#51 = Utf8 firstElement:
#52 = NameAndType #70:#71 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#53 = NameAndType #70:#72 // append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
#54 = NameAndType #73:#74 // toString:()Ljava/lang/String;
#55 = Utf8 cn/gd/cz/hong/Main
#56 = Utf8 java/lang/Object
#57 = Utf8 java/lang/System
#58 = Utf8 out
#59 = Utf8 Ljava/io/PrintStream;
#60 = Utf8 java/io/PrintStream
#61 = Utf8 println
#62 = Utf8 (Ljava/lang/String;)V
#63 = Utf8 valueOf
#64 = Utf8 (I)Ljava/lang/Integer;
#65 = Utf8 java/util/List
#66 = Utf8 add
#67 = Utf8 (Ljava/lang/Object;)Z
#68 = Utf8 get
#69 = Utf8 (I)Ljava/lang/Object;
#70 = Utf8 append
#71 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#72 = Utf8 (Ljava/lang/Object;)Ljava/lang/StringBuilder;
#73 = Utf8 toString
#74 = Utf8 ()Ljava/lang/String;
{
public cn.gd.cz.hong.Main();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/gd/cz/hong/Main;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=3, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello world!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: new #5 // class java/util/ArrayList
11: dup
12: invokespecial #6 // Method java/util/ArrayList."":()V
15: astore_1
16: aload_1
17: iconst_1
18: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
21: invokeinterface #8, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
26: pop
27: aload_1
28: iconst_2
29: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
32: invokeinterface #8, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
37: pop
38: aload_1
39: iconst_3
40: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
43: invokeinterface #8, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
48: pop
49: aload_1
50: iconst_0
51: invokeinterface #9, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
56: checkcast #10 // class java/lang/Integer
59: astore_2
60: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
63: new #11 // class java/lang/StringBuilder
66: dup
67: invokespecial #12 // Method java/lang/StringBuilder."":()V
70: ldc #13 // String firstElement:
72: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
75: aload_2
76: invokevirtual #15 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
79: invokevirtual #16 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
82: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
85: return
LineNumberTable:
line 8: 0
line 9: 8
line 10: 16
line 11: 27
line 12: 38
line 13: 49
line 14: 60
line 15: 85
LocalVariableTable:
Start Length Slot Name Signature
0 86 0 args [Ljava/lang/String;
16 70 1 intList Ljava/util/List;
60 26 2 firstElement Ljava/lang/Integer;
LocalVariableTypeTable:
Start Length Slot Name Signature
16 70 1 intList Ljava/util/List<Ljava/lang/Integer;>;
}
SourceFile: "Main.java"