Java 虛擬機規范
每個Class文件都是由8字節為單位的字節流組成,所有的16位、32位和64位長度的數據將被構造成 2個、4個和8個8字節單位來表示。多字節數據項總是按照Big-Endian①的順序進行存儲。在Java SDK中,訪問這種格式的數據可以使用java.io.DataInput、java.io.DataOutput等接口和java.io.DataInputStream 和java.io.DataOutputStream等類來實現。
Class文件中定義了u1,u2和u4,分別代表了1、2和4個字節的無符號數
在Java SDK中這些類型的數據可以通過實現接口java.io.DataInput 中的readUnsignedByte、readUnsignedShort和readInt方法進行讀取。
每一個Class文件對應于一個如下所示的ClassFile結構體。
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]; }
在Class文件中,各項按照嚴格順序連續存放的,它們之間沒有任何填充或對齊作為各項間的分隔符號。ClassFile結構體中,各項的含義描述如下
magic
魔數,魔數的唯一作用是確定這個文件是否為一個能被虛擬機所接受的Class文件。魔數值固定為0xCAFEBABE,不會改變minor_version、major_version
副版本號和主版本號,minor_version和major_version的值分別表示Class文件的副、主版本。它們共同構成了Class文件的格式版本號。constant_pool_count 常量池計數器
constant_pool_count的值等于constant_pool表中的成員數加1。constant_pool表的索引值只有在大于0且小于constant_pool_count時才會被認為是有效的。-
constant_pool[] 常量池
constant_pool是一種表結構,它包含Class文件結構及其子結構中引用的所有字符串常量、類或接口名、字段名和其它常量。常量池中的每一項都具備相同的格式特征——第一個字節作為類型標記用于識別該項是哪種類型的常量,稱為“tag byte”。常量池的索引范圍是1至constant_pool_count?1。0是無效索引,表示不指向任何常量。CON-STANT_Long_info和CONSTANT_Double_info各占兩個位置。比如下面的常量池:
Paste_Image.png access_flags
訪問標志access_flags是一種掩碼標志,用于表示某個類或者接口的訪問權限及基礎屬性。指出class文件定義的是類還是接口,訪問級別是public還是private,等等。this_class 和super_class
類索引,this_class的值必須是對constant_pool表中項目的一個有效索引值。constant_pool表在這個索引處的項必須為CONSTANT_Class_info類型常量。u2類型的常量池索引,分別給出類名和超類名。class文件存儲的類名類似完全限定名,但是把點換成了斜線,Java語言規范把這種名字叫作二進制名。除java.lang.Object之外,其他類都有超類,所以superClass只在Object.class中是0,在其他class文件中必須是有效的常量池索引。interfaces_count
接口計數器,interfaces_count的值表示當前類或接口的直接父接口數量。interfaces[]
接口表,interfaces[]數組中的每個成員的值必須是一個對constant_pool表中項目的一個有效索引值,它的長度為interfaces_count。給出該類實現的所有接口的名字。
+fields_count 和fields[]
字段計數器和字段表,fields_count的值表示當前Class文件fields[]數組的成員個數。fields[]數組中每一項都是一個field_info結構的數據項,它用于表示該類或接口聲明的類字段或者實例字段。
field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }
methods_count 和methods[]
方法計數器和方法表,methods_count的值表示當前Class文件methods[]數組的成員個數。Methods[]數組中每一項都是一個method_info結構的數據項。
method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }
attributes_count和attributes[]
屬性計數器和屬性表,attributes_count的值表示當前Class文件attributes表的成員個數。attributes表中每一項都是一個attribute_info結構的數據項。屬性(Attributes)在Class文件格式中的ClassFile結構、field_info 結構,method_info結構和Code_attribute結構都有使用。
所有屬性的通用格式如下:
attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; }