1. 程式人生 > 實用技巧 >虛擬機器基礎概念-Class檔案結構

虛擬機器基礎概念-Class檔案結構

2 Class檔案結構

2.1. Class檔案的組成

組成部分 功能
Magic Number 檔案識別符號
Minor version Jdk的版本號中的小版本號
Major version Jdk版本號中的大版號
constant_pool_count 常量池中常量的數量
constant_pool 常量池的具體實現,常量池中具體有什麼內容
access_flags 整個class檔案的修飾符
this_class 當前類的名稱
super_class 當前類的父類名稱
interfaces_count 實現介面的數量
Interfaces 具體實現了哪些介面
Fields_count 屬性的數量

fields 具體有哪些屬性
Methods_count 具有方法的數量
methods 具體具有哪些方法
Attributes_count – u2 附加屬性的數量
attributes 具體有哪些附加屬性

2.2. Magic Number、Minor Number、Major Number

位元組碼檔案如下所示,其中前四位位元組碼標識是Magic Number。例如這裡的CA FE BA BE,表示該位元組碼檔案是java編譯後的class檔案。
第五位和第六位表示JDK版本號的小版本,即Minor Number,第七位和第八位表示JDK版本號的小版本,即Major Number。例如這裡採用JDK1.8,所以Major Number為00 34,因為JDK1.8在所有JDK中序號為52,JDK1.7為51;這裡使用的又是JDK1.8中的第一個版本,所以為JDK1.8.0,所以這裡的Minor Number為00 00。

在這裡插入圖片描述

2.3. constant_pool_count、constant_pool

constant_pool_count表示常量池中常量的數量,但是該數需減去一,因為第0位不儲存任何常量,作為一個備用位置,當不使用常量池中任何常量時指向該位置。例如,圖中00 10就表示常量池中常量的數量為16-1=15個。constant_pool_count佔用了四個16進位制位,又因為第0位不儲存任何常量,所以constant_pool_count的最大值為216-1-1 = 65536 -2 = 65534,即最多可以存放65534個常量。
constant_pool表示常量池中具體的內容了,所佔地址位數不限。
常量池的常量型別分類,共有14種,具體如下:

tag 名稱 length Bytes
1 CONSTANT_Uft8_info UTF-8字串佔用的長度 長度位length的字串
3 CONSTANT_Integer_info 4位元組 Big-Dndian(高位在前)儲存的int值
4 CONSTANT_Float_info 4位元組 Big-Dndian(高位在前)儲存的float值
5 CONSTANT_Long_info 8位元組 Big-Dndian(高位在前)儲存的long值
6 CONSTANT_Double_info 8位元組 Big-Dndian(高位在前)儲存的double值
7 CONSTANT_Class_info 2位元組 指向類的全限定名項的索引
8 CONSTANT_String_info 2位元組 指向字串字面量的索引
9 CONSTANT_Fieldref_info 2位元組 指向宣告欄位的類或介面描述符CONSTANT_Class_info的索引項
2位元組 指向欄位描述符CONSTANT_NameAndType的索引項
10 CONSTANT_Methodref_info 2位元組 指向宣告欄位的類或介面描述符CONSTANT_Class_info的索引項
2位元組 指向欄位描述符CONSTANT_NameAndType的索引項
11 CONSTANT_interfaceMethodref_info 2位元組 指向宣告欄位的類或介面描述符CONSTANT_Class_info的索引項或指向欄位描述符CONSTANT_NameAndType的索引項
2位元組 指向欄位描述符CONSTANT_NameAndType的索引項
12 CONSTANT_NameAndType_info 2位元組 指向該欄位或方法名稱常量項的索引
2位元組 指向該欄位方法描述符常量項的索引
15 CONSTANT_MethodHandle_info 1位元組 reference_kind:1-9之間的一個值,決定了方法控制代碼的型別,方法控制代碼型別的值表示方法控制代碼的位元組碼行為
2位元組 Reference_index:對常量池的有效索引
16 CONSTANT_MethodType_info 2位元組 Descriptor_index:指向UTF8-info結構表示的方法描述符
18 CONSTANT_InvokeDynamic_info 2位元組 Bootstrap_method_attr_index:當前class檔案引導方法表的bootstrap_methods[]陣列的有效索引
2位元組 Name_and_type_index:指向NameAndType_info表示的方法名和方法描述符
Constant_pool常量池的應用舉例:如下圖為常量池中的內容,在常量池中的1號位置處,資料型別為CONSTANT_Methodref_info,該資料型別共儲存4個位元組內容,其中前兩個位元組為指向宣告欄位的類(儲存在常量池中的第三號位置),後兩個位元組為指向指向欄位描述符CONSTANT_NameAndType的索引項(儲存在常量池的第13號位置處)。上述介紹表現在位元組碼檔案中,如位元組碼圖中的綠色位置所示。
在這裡插入圖片描述
在這裡插入圖片描述

2.4. access flags

該class檔案的修飾符,例如public、final等,這些不是單選的,可以是擁有多個型別,多個型別最終是疊加到一起,用一個十六進位制數值表示的所有的。
在這裡插入圖片描述

2.5. this_class、super_class

this_class表示當前類,儲存的是當前類在常量池中類的全限定名項索引的位置;super_class表示當前類的父類,儲存的是當前類的父類在常量池中類的全限定名項索引的位置。
例如這裡this_class儲存的cp_info #2表示當前類儲存在常量池中的二號位置,而類的名稱儲存在cp_info #14位置處,其具體名稱為“<src/Test/test>”。這裡面就存在常量池中各變數的互相引用。
在這裡插入圖片描述

2.6. Fields

1)Fields屬性中儲存的內容
在這裡插入圖片描述

其中,access_flags表示屬性的型別,例如有public、private、volatile等;name_index表示屬性的名稱,該名稱放在常量池中;descriptor_index表示資料型別,例如int、flaot、long等,不過是該型別相對應的縮寫;attributes_count表示附加屬性的數量,attributes表示附加屬性具體有哪些。
2)Access_flags表示的屬性型別具體有:
在這裡插入圖片描述

3)descriptor_index表示資料型別具體有:
在這裡插入圖片描述

2.7. Methods

1) Methods中的內容
在這裡插入圖片描述

其中,access_flags表示該方法的修飾符,例如有public、private、volatile等;name_index表示方法的名稱,該名稱放在常量池中;descriptor_index表示方法的傳入形式,例如void a()、int a()、int a(int para1, int[] para2)等,不過是這些型別的縮寫形式;attributes_count表示附加屬性的數量,attributes表示附加屬性具體有哪些。
注意事項:
Method中有類預設的構造方法,而且在該構造方法中會實現父類中的構造方法(無參構造方法)