分析一個java class文件

分析一個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文件分析完畢。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章