Java類檔案結構
一、概述
Java實作了跨平台,“一次編譯,到處運作”。實作平台語言無關性的基礎仍然是虛拟機的位元組碼存儲格式。使用java、JRuby等其他語言的編譯器都可以将程式編譯成class檔案,虛拟機并不關心class檔案的來源是什麼,隻要它符合class檔案的結構就可以在java虛拟機上運作了。
二、class類檔案的結構概述:
1、基本内容: Class檔案是一組以位元組(8位)為機關的二進制流,各個資料項嚴格按照順序緊湊地排列在class檔案中,中間沒有任何分隔符,這使得class檔案的所有内容幾乎全部成為程式運作的必要資料。當然,存儲資料項時,有的資料是大于8位的,這時則會按照高位在前的方式分割成若幹個8位位元組進行存儲。
2、具體存儲結構分類:
根據java虛拟機規範規定,class檔案格式采用一種類似C語言體系結構的僞結構來存儲,這種僞結構隻有兩種資料類型:無符号數和表。
無符号數:屬于基本的資料類型,可以用來描述數字、索引引用、數量值,或者按照UTF-8編碼構成的字元串值。
表:是由多個無符号數或其他表作為資料項構成的複合資料類型。所有表習慣以“_info”結尾。(整個class檔案就是一張表)。
強調:class的結構不像xml等描述語言,由于它沒有任何分隔符,每個位元組的順序長度等都不允許改變或是調換。
三、class類檔案的結構詳述:
Class類檔案由以下幾部分組成:
(1)魔數、(2)class檔案的版本号、(3)常量池、(4)通路标志、(5)類索引、父親索引與接口索引集合、(6)字段表集合、(7)方法表集合、(8)屬性表集合。
首先給出一個樣例,接着按照樣例說明每個組成部分的含義:
圖1.1
注意:上面藍色底部線和綠色底部線經過的部分共同構成了常量位(後面一部分的也是,之後說明)。
接着上面的介紹,我們進行下面的分析。常量池完了之後緊接着的是下面的通路标志位。
類索引、父親索引與接口索引集合:OX0001,OX0003,OX0000分别表示類索引為1, 父類索引為3、接口索引集合大小為0.
字段表集合:ox0001:fields_count; ox0002:access_flags; ox0005:name_index,
Ox0006:description_index.
詳細介紹:
1、魔數:
每個class檔案的頭四個位元組稱為魔數,它的唯一作用是用于确定這個檔案是否為一個能被虛拟機接收的class檔案。(很多檔案例如jpg、png格式的檔案都是通過魔數來區分的,并不是字尾名,因為字尾名是可以更改的,不安全)。
Java 虛拟機class檔案的魔數規定為:OXCAFEBABE
2、版本号:
版本号分為次版本号 和 主版本号。各占兩個位元組。
JDK 1.7 版本号為 51; JDK1.6 為50
3、常量池:
常量池是class檔案結構中與其他項目關聯最多的資料類型,也是占用class檔案空間最大的資料項目之一。同時它是表類型的(是第一個出現表類型存儲結構的資料項目)。
常量池包括下面幾項:
(1)常量池容量計數值:因為常量池長度是不固定的,是以應該有一個容量計數池來計數。 需要注意的是:常量池容量計數器是從1開始計數的,其他都是從0開始。
緊接着常量計數器之後,常量池中主要存放兩大類常量:字面量 和 符号引用。
自面量:字面量比較接近于java語言層面的常量概念,如文本字元串、被申明的final常量等。
符号引用:屬于編譯原理方面的概念。基本包括了以下幾個方面:類和接口的全限定名、字段的名稱和描述符、方法的名稱和描述符。
(2)常量池項目類型标志位:(注意标志位沒有2号)
總共是11種。但是這11種常量類型各自均有自己的結構。
例如:
圖1.1分析:從常量池開始,容量計數器完後接着是OX 07,這個表示項目類型選中的是7号CONSTANT_Class_info,接着0x 0002表示的是常量u2:name_index.
緊接着回到項目類型标志位中設定tag = ox01,後面設定的是length.為ox001D,也就是29位,緊接着29位表示的就是資料内容。
現在,圖1.1中的内容應該就差不多了解了。
其他類型的我們在這裡省略了。
4、通路标志位:
緊接着常量位,是通路标志位。這個标志位用于識别一些類或是接口層次的通路資訊,包括:這個class是類還是接口,是否定義類型為pulbic類型,是否為final等等。
5、類索引、父親索引與接口索引集合:
Class檔案由這三項來确定這個類的繼承關系。類索引、父類索引和接口索引都按順序排列在通路标志之後。
6、字段表集合:
字段表用于描述 接口或類中聲明的變量。字段包括了類級别變量或執行個體級别變量,但不包括在方法内部聲明的變量。
例如有:字段的作用域(public、private、protected等),static、final等。
字段表集合包括以下内容(注意下面四個并不是并列的,而是包含關系):