分析一個java class文件
雖然現在class文件可以直接通過 javap -verbose命令行來直接看結構清晰的class文件,也可以通過jclasslib這種idea的插件來通過有ui交互的方式來查看,但是分析一個class文件,有助於幫我們更好的瞭解class文件的結構,下面是要分析的class文件的java代碼:
package com.example.jvm;
public class Test {
private int age = 99;
public static void main(String[] args) {
System.out.println("hello world");
}
}
編譯成Test.class文件後,我們以16進制的方式打開,數據如下:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
00 01 00 0C 00 00 00 37 00 02 00 01 00 00 00 09
B2 00 03 12 04 B6 00 05 B1 00 00 00 02 00 0D 00
00 00 0A 00 02 00 00 00 08 00 08 00 09 00 0E 00
00 00 0C 00 01 00 00 00 09 00 13 00 14 00 00 00
01 00 15 00 00 00 02 00 16
class文件的結構如下(java8虛擬機規範中查詢):
ClassFile {
u4 magic; //魔數
u2 minor_version; //副版本號
u2 major_version; //主版本號
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
4個字節的魔數
CA FE BA BE
接下來是2個字節的副版本號和2個字節的主版本號,他們共同構成了class文件的格式版本號
CA FE BA BE 00 00 00 34
可以看出副版本號是0,主版本號是52
接下來是兩個字節的常量池計數器(constant_pool_count),constant_pool_count的值等於常量池中的成員數加1。
CA FE BA BE 00 00 00 34 00 26
0x0026 轉爲10進制是38,所以常量池中的成員數是 37。
然後是常量池數組的解析constant_pool,常量池中的每個值是由一個字節的tag,然後根據tag得到具體的數據結構來進行解析的,我們先讀取常量池中的第一個字節,下面是tag表對應的關係:
類型 | 標誌 | 描述 |
---|---|---|
CONSTANT_utf8_info | 1 | UTF-8編碼的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮點型字面量 |
CONSTANT_Long_info | 5 | 長整型字面量 |
CONSTANT_Double_info | 6 | 雙精度浮點型字面量 |
CONSTANT_Class_info | 7 | 類或接口的符號引用 |
CONSTANT_String_info | 8 | 字符串類型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符號引用 |
CONSTANT_Methodref_info | 10 | 類中方法的符號引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中方法的符號引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的符號引用 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_MothodType_info | 16 | 標誌方法類型 |
CONSTANT_InvokeDynamic_info | 18 | 表示一個動態方法調用點 |
接下來我們讀取讀一個常量池的cp_info的值的tag是
CA FE BA BE 00 00 00 34 00 26 0A
0x0A的值十進制是10,可以得到該cp_info是CONSTANT_Methodref_info,結構如下
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
對應的十六進制裏面的數據是
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 所以:
CONSTANT_Methodref_info {
u1 tag = 10;
u2 class_index = 7; // 常量池表的有效索引,數據接哦古爲CONSTANT_Class_info
u2 name_and_type_index = 23;//常量池表的有效索引,對應的結構爲CONSTANT_Fieldref_info,表示當前字段或方法的名字和描述符
}
index爲2的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
所以具體的數據爲:
CONSTANT_Fieldref_info {
u1 tag = 9;
u2 class_index = 6;
u2 name_and_type_index = 24;
}
index爲3的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
所以具體數據爲:
CONSTANT_Fieldref_info {
u1 tag = 9;
u2 class_index = 25;
u2 name_and_type_index = 26;
}
index爲4的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
所以具體數據爲:
CONSTANT_String_info {
u1 tag = 08;
u2 string_index = 27; //對應常量池中index爲27的 CONSTATN_utf8_info的對象
}
index爲5的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
所以具體數據爲:
CONSTANT_Methodref_info {
u1 tag = 10;
u2 class_index = 28;
u2 name_and_type_index = 29;
}
index爲6的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
所以具體數據爲:
CONSTANT_Class_info {
u1 tag = 7;
u2 name_index = 30; //常量池中的索引,對應的結構爲CONSTANT_Utf8_info,表示一個有效類名稱的內部形式,例如com/example/jvm/Test
}
index爲7的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
所以具體數據爲:
CONSTANT_Class_info {
u1 tag = 7;
u2 name_index = 31;
}
index爲8的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 3; //代表字符串的字節數
u1 bytes[length] = "age"; // (0x61, 0x67, 0x65) 代表字符串的字節數組
}
index爲9的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 1; //代表字符串的字節數
u1 bytes[length] = "I"; //(0x49)
}
index爲10的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 6;
u1 bytes[length] = "<init>";
}
index爲11的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 36;
u1 bytes[length] = "()V";//方法簽名,無參方法,無返回值
}
index爲12的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 4;
u1 bytes[length] = "Code";
}
index爲13的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 15;
u1 bytes[length] = "LineNumberTable"; //方法對應的行號
}
index爲14的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 18;
u1 bytes[length] = "LocalVariableTable";//方法的局部變量表
}
index爲15的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
所以具體數據爲:
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 4;
u1 bytes[length] = "this";
}
index爲16的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 22;
u1 bytes[length] = "Lcom/example/jvm/Test;"; //L是字段描述符L代表reference類型, I代表int 具體可以查java虛擬機規範的4.3.2章
}
index爲17的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 4;
u1 bytes[length] = main;
}
index爲18的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 22;
u1 bytes[length] = "([Ljava/lang/String;)V"; //[代表一維數組
}
index爲19的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 4;
u1 bytes[length] = "args";
}
index爲20的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 19;
u1 bytes[length] = "[Ljava/lang/String;";
}
index爲21的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 10;
u1 bytes[length] = "SourceFile";
}
index爲22的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 9;
u1 bytes[length] = "Test.java";
}
index爲23的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
CONSTANT_NameAndType_info { //表示字段或者方法
u1 tag = 12;
u2 name_index = 10; //常量池中index爲10的數據結構是 CONSTANT_Utf8_info 值爲<init>
u2 descriptor_index = 11; //index爲11的數據結構是CONSTATN_Utf8_info 值爲 ()V
} //該類的構造方法
index爲24的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
CONSTANT_NameAndType_info { //表示字段或者方法
u1 tag = 12;
u2 name_index = 8; //常量池中index爲8的數據結構是CONSTANT_Utf8_info 值爲age
u2 descriptor_index = 9; //index爲9的數據格式是CONSTATN_Utf8_info 值爲 I
} //該類的一個屬性 屬性名爲age 類型是int
index爲25的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
CONSTANT_Class_info {
u1 tag = 7;
u2 name_index = 32; // java/lang/System
}
index爲26的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
CONSTANT_NameAndType_info {
u1 tag = 12;
u2 name_index = 33; // out
u2 descriptor_index = 34; // Ljava/io/PrintStream;
}
index爲27的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 11;
u1 bytes[length] = "hello world";
}
index爲28的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
CONSTANT_Class_info {
u1 tag = 7;
u2 name_index = 35; // java/io/PrintStream
}
index爲29的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
CONSTANT_NameAndType_info {
u1 tag = 12;
u2 name_index = 36; // println
u2 descriptor_index = 37; // (Ljava/io/String;)V
}
index爲30的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 20;
u1 bytes[length] = "com/example/jvm/Test";
}
index爲31的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 16;
u1 bytes[length] = "java/lang/Object";
}
index爲32的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 16;
u1 bytes[length] = "java/lang/System";
}
index爲33的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 3;
u1 bytes[length] = "out";
}
index爲34的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 21;
u1 bytes[length] = "Ljava/io/PrintStream;";
}
index爲35的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 19;
u1 bytes[length] = "java/io/PrintStream";
}
index爲36的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 7;
u1 bytes[length] = "println";
}
index爲37的十六進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
CONSTANT_Utf8_info {
u1 tag = 1;
u2 length = 21;
u1 bytes[length] = "(Ljava/lang/String;)V";
}
到此常量池區的數據就解析完了,安裝Java虛擬機規範的結構要求下面是 u2 access_flags:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
u2 access_flags = 0x21; //可以查java虛擬機規範表4-1 得知爲ACC_PUBLIC | ACC_SUPER
接下來是 u2 this_class:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
u2 this_class = 0x06; //是常量池表中的一個有效索引值,查常量池表可得知是類Test的CONSTANT_Class_info數據
接下來是u2 super_class:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
u2 super_class = 0x07; //也是常量池中的一個索引,查常量池表可得知是類Object的CONSTANT_Class_info數據
再接下來是 u2 interfaces_count:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
u2 interfaces_count = 0x00; //接口計數器
由於 interfaces_count = 0;所以interfaces[]爲空,接下來直接是fields_count:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
u2 fields_count = 0x01;
接下來是 field_info fields[fields_count],其中field_info的結構如下:
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
field_info {
u2 access_flags = 0x02; // ACC_PRIVATE
u2 name_index = 0x08; //常量池索引,查常量池可得爲 age
u2 descriptor_index = 0x09; //常量池索引,查常量池可得爲 I 代表int類型
u2 attributes_count = 0x00;
attribute_info attributes[attributes_count]; // 具體的結構可查java虛擬機規範
}
接下來是u2 methods_count:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
u2 methods_count = 0x02;
接下來是方法表,由methods_count=0x02可知方法表的大小爲2,方法表的item method_info結構如下:
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
index爲0的method_info的到attributes十六進制爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
method_info {
u2 access_flags = 0x01; //ACC_PUBLIC
u2 name_index = 10; // <init>
u2 descriptor_index = 11; //()V
u2 attributes_count = 1;
}
接下來是方法的attributes,我們首先先看一下attribute_info的數據結構:
attribute_info {
u2 attribute_name_index;
u4 attribute_length;
u1 info[attribute_length];
}
所以方法的index爲0的attribute到attribute_length的16進制數據爲:
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
attribue_info {
u2 attribute_name_index = 12; // Code
u4 attribute_length = 57;
}
所以index爲0的method_info的第一個屬性爲Code,Code屬性的結構如下:
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{
u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
CA FE BA BE 00 00 00 34 00 26 0A 00 07 00 17 09
00 06 00 18 09 00 19 00 1A 08 00 1B 0A 00 1C 00
1D 07 00 1E 07 00 1F 01 00 03 61 67 65 01 00 01
49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56
01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75
6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61
6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00
04 74 68 69 73 01 00 16 4C 63 6F 6D 2F 65 78 61
6D 70 6C 65 2F 6A 76 6D 2F 54 65 73 74 3B 01 00
04 6D 61 69 6E 01 00 16 28 5B 4C 6A 61 76 61 2F
6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00
04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C
61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F
75 72 63 65 46 69 6C 65 01 00 09 54 65 73 74 2E
6A 61 76 61 0C 00 0A 00 0B 0C 00 08 00 09 07 00
20 0C 00 21 00 22 01 00 0B 68 65 6C 6C 6F 20 77
6F 72 6C 64 07 00 23 0C 00 24 00 25 01 00 14 63
6F 6D 2F 65 78 61 6D 70 6C 65 2F 6A 76 6D 2F 54
65 73 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F
4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61
6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01
00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74
53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69
6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07
70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61
2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
Code_attribute {
u2 attribute_name_index = 12;
u4 attribute_length = 57;
u2 max_stack = 2;
u2 max_locals = 1;
u4 code_length = 11;
u1 code[code_length] = ...;
u2 exception_table_length = 0;
}
因爲code_length長度爲11,我們需要往後數11個字節,爲具體的操作指令:
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
第一個操作指令是0x2A,位於codes第0個字節下面的LineNumberTable中start pc有用 可以查操作指令的手冊發現0x2A指令是aload_0 // 00|01 = 01,對應的是方法的引用
第二個操作指令是0xB7,codes[1] 是invokespecial 00, 01
第三個操作指令是0x2A,codes[4] 是aload_0
第四個操作指令是0x10, codes[5] 是bipush
第五個操作指令是0xB5,codes[7] 是putfield
第六個操作指令是0xB1,codes[10] 是return
接下來是兩個字節的exception_table_length
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
Code_attribute {
u2 attribute_name_index = 12;
u4 attribute_length = 57;
u2 max_stack = 2;
u2 max_locals = 1;
u4 code_length = 11;
u2 exception_table_length = 0;
}
接下來是兩個字節的attributes_count = 2
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
接下來是兩個字節attributes,按照上面的結構直接可知第一個attribute爲:
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
attribute {
u2 attribute_name_index = 13; //查常量池可知爲 LineNumberTable
u4 attribute_length = 10;
}
LineNumberTable屬性的結構如下:
LineNumberTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 line_number_table_length;
{
u2 start_pc;
u2 line_number;
} line_number_table[line_number_table_length];
}
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
LineNumberTable_attribute {
u2 attribute_name_index = 13;
u4 attribute_length = 10;
u2 line_number_table_length = 2;
line_number_table[0] = {
u2 start_pc = 0; //對應的是上面code的所有,如 0 對應的是 aload_0
u2 line_number = 3; //java文件中的行號
};
line_number_table[1] = {
u2 start_pc = 4;
u2 line_number = 5;
};
}
接下來是第二個屬性值:
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
attribute {
u2 attribute_name_index = 14; //查常量池可知爲 LocalVariableTable
u4 attribute_length = 10;
}
LocalVariableTable的數據表結構爲:
LocalVariableTable_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 local_variable_table_length;
{
u2 start_pc;
u2 length;
u2 name_index;
u2 descriptor_index;
u2 index;
} local_variable_table[local_variable_table_length];
}
21 00 06 00 07 00 00 00 01 00 02 00 08 00 09 00
00 00 02 00 01 00 0A 00 0B 00 01 00 0C 00 00 00
39 00 02 00 01 00 00 00 0B 2A B7 00 01 2A 10 63
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
所以LocalVariableTable_attribute的數據爲:
LocalVariableTable_attribute {
u2 attribute_name_index = 14;
u4 attribute_length = 12;
u2 local_variable_table_length = 1;
local_variable_table[0] =
{
u2 start_pc = 0;
u2 length = 11;
u2 name_index = 15; // this
u2 descriptor_index = 16; //Lcom/example/jvm/Test;
u2 index = 0;
};
}
至此<init>放方法的字節碼就分析完了,我們把所有結構整合到一起:
method_info {
u2 access_flags = 0x01; //ACC_PUBLIC
u2 name_index = 10; // <init>
u2 descriptor_index = 11; //()V
u2 attributes_count = 1;
attributes = {
Code_attribute {
u2 attribute_name_index = 12;
u4 attribute_length = 57;
u2 max_stack = 2;
u2 max_locals = 1;
u4 code_length = 11;
codes = {
codes[0] : 0x2A; // aload_0
codes[1] = 0xB7; // invokespecial
codes[4] = 0x2A; // aload_0
codes[5] = 0x10; // bipush
codes[7] = 0xB5; // putfield
codes[10] = 0xB1; // return
};
u2 exception_table_length = 0;
u2 attributes_count = 2;
LineNumberTable_attribute {
u2 attribute_name_index = 13;
u4 attribute_length = 10;
u2 line_number_table_length = 2;
line_number_table[0] = {
u2 start_pc = 0; //對應的是上面code的所有,如 0 對應的是 aload_0
u2 line_number = 3; //java文件中的行號
};
line_number_table[1] = {
u2 start_pc = 4;
u2 line_number = 5;
};
}
LocalVariableTable_attribute {
u2 attribute_name_index = 14;
u4 attribute_length = 12;
u2 local_variable_table_length = 1;
local_variable_table[0] =
{
u2 start_pc = 0;
u2 length = 11;
u2 name_index = 15; // this
u2 descriptor_index = 16; //Lcom/example/jvm/Test;
u2 index = 0;
};
}
},
}
}
接下來就可以直接分析main方法了,main方法的分析過程跟<init>的過程是一樣的,這裏我們就一次性搞掉吧
B5 00 02 B1 00 00 00 02 00 0D 00 00 00 0A 00 02
00 00 00 03 00 04 00 05 00 0E 00 00 00 0C 00 01
00 00 00 0B 00 0F 00 10 00 00 00 09 00 11 00 12
00 01 00 0C 00 00 00 37 00 02 00 01 00 00 00 09
B2 00 03 12 04 B6 00 05 B1 00 00 00 02 00 0D 00
00 00 0A 00 02 00 00 00 08 00 08 00 09 00 0E 00
00 00 0C 00 01 00 00 00 09 00 13 00 14 00 00 00
01 00 15 00 00 00 02 00 16
method_info {
u2 access_flags = 0x09; //ACC_PUBLIC | ACC_STATIC
u2 name_index = 17; // main
u2 descriptor_index = 18; //([Ljava/lang/String;)V
u2 attributes_count = 1;
attributes = {
Code_attribute {
u2 attribute_name_index = 12;
u4 attribute_length = 55;
u2 max_stack = 2;
u2 max_locals = 1;
u4 code_length = 9;
codes = {
codes[0] = 0xB2; 0 (第幾個字節 start pc有用) // getstatic (0x00 << 8) | (0x03) = 0x03;<java/lang/System.out>
codes[3] = 0x12; 3 // ldc 推送字符串到常量池 ldc 0x04(<Hello World>)
codes[5] = 0xB6; 5 // invokevirtual (0x00 << 8) | 0x05 = 0x05 //<java/io/PrintStream.println>
codes[8] = 0xB1; 8 // return
};
u2 exception_table_length = 0;
u2 attributes_count = 2;
LineNumberTable_attribute {
u2 attribute_name_index = 13;
u4 attribute_length = 10;
u2 line_number_table_length = 2;
line_number_table[0] = {
u2 start_pc = 0; //codes的索引 0 是 getstatic
u2 line_number = 8; //java文件中的行號
};
line_number_table[1] = {
u2 start_pc = 8;
u2 line_number = 9;
};
},
LocalVariableTable_attribute {
u2 attribute_name_index = 14;
u4 attribute_length = 12;
u2 local_variable_table_length = 1;
local_variable_table[0] =
{
u2 start_pc = 0;
u2 length = 9;
u2 name_index = 19; // args;
u2 descriptor_index = 20; //[Ljava/lang/String;
u2 index = 0;
};
}
},
}
}
接下來是u2 attributes_count = 1:
00 00 0A 00 02 00 00 00 08 00 08 00 09 00 0E 00
00 00 0C 00 01 00 00 00 09 00 13 00 14 00 00 00
01 00 15 00 00 00 02 00 16
00 00 0A 00 02 00 00 00 08 00 08 00 09 00 0E 00
00 00 0C 00 01 00 00 00 09 00 13 00 14 00 00 00
01 00 15 00 00 00 02 00 16
SourceFileAttribut {
u2 attribute_name_index = 21;//SoruceFile
u4 attribute_length = 2; // 2個字節
u2 sourcefile_index = 22; //Test.java
}
至此一個class文件分析完畢。