魔數
每個class檔案的頭4個位元組稱為魔數(Magic Number),其值為:0xCAFEBASE,它的唯一作用是用於確定這個檔案是否為一個能被虛擬機器接受的class檔案。使用魔數而不是副檔名來進行識別主要是基於安全的考慮,因為檔案的副檔名可以隨意地被改動。
版本號碼
緊接著魔的4個位元組儲存的是class檔案的版本號碼:第5和第6個位元組是次版本號碼(Minor Version),第7和第8個位元組是主要版本號(Major Version)。java的版本是從45開始的,JDK1.1之後的每個JDK大版本發布主要版本號上加1(JDK1.0-1.1使用了45.0-45.3的版本號碼),高版本的JDK能向下相容以前版本的class檔案,但不能運行以後版本的class檔案,即使檔案格式並未發生變化。JDK1.2對應主要版本號為46,JDK1.3為47,依此類推。
常量池
緊接著主次版本號碼之後的是常量池入口,常量池是class檔案結構中與其它項目關聯最多的資料類型,也是佔用class檔案空間最大的資料項目之一,同時它還是class檔案中第一個出現的表類型資料項目。
由於常量池中常量的資料是不固定的,所以在常量池的入口需要放置一薦u2類型的資料,代表常量池容量計算值(constant_pool_count)。與Java語言習慣不一樣的是,這個容量計數是從1而不是0開始的。將第0項常量出來的目的是為了滿足後面某些指向常量池的索引值的資料在特定情況下需要表達“不引用任何一個常量池項目”的意思。class檔案結構中只有常量池的容量計數是從1開始,對於其它集合類型,包括介面索引集合,欄位表集合,方法表集合的容量計算都是從0開始的。
常量池中主要存放兩大類常量:字面量(Literal)和符號引用(Symbolic References)。字面量比較接近於Java語言層面的常量概念,如文本字串,被聲明為final的常量值等。而符號引用則屬性編譯原理方面的概念,包含了下面三類常量:
a.類和介面的全限定名(Fully Qualified Name)
b.欄位的名稱和描述符(Descriptor)
c.方法的名稱和描述符
常量池中的每一項常量都是一個表,共有11種結構各不相同的表結構資料,這11種表都有一個共同的特點,就是表開始的第一位是一個u1類型的標誌位,代表當前這個常量屬性哪種常量類型,11種常量類型具體含義如下:
各常量項結構: