當你用16進制編譯器打開一個java文件,你就能夠看到相似這個的Java文件的模板。 java
Class 文件是一組以 8 位字節爲基礎單位的二進制流,各個數據項目嚴格按照順序緊湊地排列在 Class 文件中,中間沒有任何分隔符。Java 虛擬機規範規定 Class 文件採用一種相似 C 語言結構體的僞結構來存儲數據,這種僞結構中只有兩種數據類型:無符號數和表,咱們以後也主要對這兩種類型的數據類型進行解析。程序員
_info
結尾。0xCAFEBABE
,它能夠用來肯定這個文件是否爲一個能被虛擬機接受的 Class 文件(這經過擴展名來識別文件類型要安全,畢竟擴展名是能夠隨便修改的)。
後 4 個字節則是當前 Class 文件的版本號,其中第 五、6 個字節是次版本號,第 七、8 個字節是主版本號。安全
從第 9 個字節開始,就是常量池的入口,常量池是 Class 文件中:編碼
常量池的開始的兩個字節,也就是第 九、10 個字節,放置一個 u2 類型的數據,標識常量池中常量的數量 cpc (constant_pool_count),這個計數值有一個十分特殊的地方,就是它是從 1 開始而不是從 0 開始的,也就是說若是 cpc = 22,那麼表明常量池中有 21 項常量,索引值爲 1 ~ 21,第 0 項常量被空出來,爲了知足後面某些指向常量池的索引值的數據在特定狀況下須要表達「不引用任何一個常量池項目」時,將讓這個索引值指向 0 便可。spa
常量池中記錄的是代碼出現過的全部 token(類名,成員變量名等,也是咱們接下來要修改的地方)以及符號引用(方法引用,成員變量引用等),主要包括如下兩大類常量:3d
常量池中的每一項常量都經過一個表來存儲。目前一共有 14 種常量,不過麻煩的地方就在於,這 14 種常量類型每一種都有本身的結構,咱們在這裏只詳細介紹兩種:CONSTANT_Class_info 和 CONSTANT_Utf8_info。code
CONSTANT_Class_info 的存儲結構爲:cdn
... [ tag=7 ] [ name_index ] ...
... [ 1位 ] [ 2位 ] ...
複製代碼
其中,tag 是標誌位,用來區分常量類型的,tag = 7 就表示接下來的這個表是一個 CONSTANT_Class_info,name_index 是一個索引值,指向常量池中的一個 CONSTANT_Utf8_info 類型的常量所在的索引值,CONSTANT_Utf8_info 類型常量通常被用來描述類的全限定名、方法名和字段名。它的存儲結構以下:blog
... [ tag=1 ] [ 當前常量的長度 len ] [ 常量的符號引用的字符串值 ] ...
... [ 1位 ] [ 2位 ] [ len位 ] ...
複製代碼