Java 虛擬機器之五:Java位元組碼檔案結構

百聯達發表於2018-09-06

一:前言

Java 虛擬機器規範中規定了 Java 虛擬機器結構、Class 類檔案結構、位元組碼指令等內容,其中對於軟體開發人員來說,類檔案結構是有必要了解的一個內容。

Java 虛擬機器的類檔案結構是一組以 8 位位元組為基礎的二進位制流,各資料專案嚴格按照順序緊湊地排列在 Class 檔案之中,中間沒有新增任何分隔符,這使得整個 Class 檔案中儲存的內容幾乎全都是程式需要的資料,沒有空隙存在。

java虛擬機器執行的就是位元組碼檔案。不論該位元組碼檔案來自何方,由哪種編譯器編譯,甚至是手寫位元組碼檔案,只要符合java虛擬機器的規範,那麼它就能夠執行該位元組碼檔案。

Java檔案:

public class Demo{
    public static void main(String args[]){
        System.out.println("Hello World.");
  }
}

Java位元組碼檔案:

二:Java類檔案(位元組碼)結構

Java 虛擬機器規範中定義了許多規範,其中有一部分定義了位元組碼的結構和規範。Java 虛擬機器規範定義了兩種資料型別來表示 Class 檔案格式,分別是:無符號數和表。

無符號數:屬於最基本的資料型別,以 u1、u2、u4、u8 六七分別代表 1 個位元組、2 個位元組、4 個位元組、8 個位元組的無符號數,無符號數可以用來描述數字、索引引用、數量值或者按照 UTF-8 編碼構成的字串值。

表:是由多個無符號數或者其他表作為資料項構成的複合資料型別,所有表都習慣性地以“_info”結尾,表用於描述有層次關係的複合結構的資料。

上面的表其實可以劃分為以下七個部分,這七個部分組成了一個完整的 Class 位元組碼檔案:

a.魔數與Class檔案版本

b.常量池

c.訪問標誌

d.類索引、父類索引、介面索引

e.欄位表集合

f.方法表集合

j.屬性表集合

1.魔數與Class檔案版本

Class 檔案的第 1 - 4 個位元組代表了該檔案的魔數(Magic Number)。它唯一的作用是確定這個檔案是否為一個能被虛擬機器接受的 Class 檔案,其值固定是:0xCAFEBABE(咖啡寶貝)。如果一個 Class 檔案的魔數不是 0xCAFEBABE,那麼虛擬機器將拒絕執行這個檔案。

Class 檔案的第 5 - 6 個位元組代表了 Class 檔案的次版本號(Minor Version),即編譯該 Class 檔案的 JDK 次版本號。

Class 檔案的第 7 - 8 個位元組代表了 Class 檔案的主版本號(Major Version),即編譯該 Class 檔案的 JDK 主版本號。

高版本的 JDK 能向下相容以前版本的 Class 檔案,但不能執行新版本的 Class 檔案。例如一個 Class 檔案是使用 JDK 1.5 編譯的,那麼我們可以用 JDK 1.7 虛擬機器執行它,但不能用 JDK 1.4 虛擬機器執行它。下表列出了各個版本 JDK 的十六進位制版本號資訊:

2.常量池

Class 檔案的第 9 - 10 個位元組用於表示常量池常量的個數(constant_pool_count),那麼緊跟著就有 constant_pool_count - 1 個常量。

每個常量池的常量都用一個型別為 cp_info 的表表示,該表有 14 個值,分別是:

3.訪問標誌

在常量池結束之後,緊接著的兩個位元組代表訪問標記(access_flags),這個標誌用於識別一些類或者介面層次的訪問資訊,包括:這個Class是類還是介面、是否定義為public型別、是否定義為abstract型別等。具體的標誌位以及標誌的含義見下表。

4.類索引、父類索引、介面索引

類索引:類索引用於確定這個類的全限定名,它用一個 u2 型別的資料表示。

父類索引:父類索引用於確定這個類的父類的全限定名,父類索引用一個u2型別的資料表示。

介面索引:介面索引集合就用來描述哪個類實現了哪些介面,這些被實現的介面將按 implements 語句(如果這個類本身就是一個介面,則應當是extends語句)後的介面順序從左到右排列在介面索引集合中。對於介面索引集合,入口第一項是 u2 型別的資料為介面計數器(interfaces_count),表示索引表的容量,而在介面計數器後則緊跟著所有的介面資訊。如果該類沒有實現任何介面,則該計數器值為0,後面介面的索引表不再佔用任何位元組。

5.欄位表集合

欄位表集合用於描述介面或者類中宣告的變數。這裡說的欄位包括類級變數和例項級變數,但不包括在方法內部宣告的區域性變數。

6.方法表集合

在欄位表後的 2 個位元組是一個方法計數器,表示類中總有有幾個方法。在欄位計數器後,才是具體的方法資料。方法表中的每個方法都用一個 method_info 表示,其資料結構如下:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-2213665/,如需轉載,請註明出處,否則將追究法律責任。

相關文章