天天看點

Class檔案結構介紹[魔數版本号]

 對于每個java程式員來說class檔案應該是每天都會接觸的,一個class檔案都對應着唯一的一個類或接口的定義資訊,但是對應class檔案的具體存儲結構并不一定很清楚,是以本文就梳理下class檔案的結構

Class檔案

 Class檔案是一組8位位元組為基礎機關的二進制流,各個資料項嚴格按照順序緊湊的排列在Class檔案中,中間沒有添加任何分隔符,整個class檔案中存儲的内容幾乎全部是程式運作的必要資料,沒有空隙存在。

 Class檔案格式采用一種類似于C語言結構體的僞結構來存儲資料,這種結構體隻有兩種資料類型:無符号數和表

無符号數

 無符号數屬于基本的資料類型,以u1,u2,u4,u8來分别表示1個位元組,2個位元組,4個位元組和8個位元組的無符号數,無符号數可以用來描述數字,索引引用,數量值或者按照UTF-8編碼結構構成字元串值。

 表是由多個無符号數或者其他表作為資料項構成的複合資料類型,所有表都習慣性地一"_info"結尾,表用于描述有層次關系的複合結構的資料,整個class檔案本質上就是一張表,class的完整結構如下:

類型 名稱 數量

u4 magic(魔數) 1

u2 minor_version(次版本号) 1

u2 major_version(主版本号) 1

u2 constant_pool_count(常量池計數器) 1

cp_info constant_pool(常量池表) constant_pool_count-1

u2 aaccess_flags(通路标志) 1

u2 this_class(類索引) 1

u2 super_class(父類索引) 1

u2 interfaces_count(接口索引計數器) 1

u2 interfaces(接口索引集合) interfaces_count

u2 fields_count(目前類字段計數器) 1

field_info fields(字段表集合) fields_count

u2 methods_count(方法計數器) 1

method_info methods(方法表集合) methods_count

u2 attributes_count(屬性計數器) 1

attribute_info attributes(屬性表集合) attributes_count

 無論是無符号數還是表,當需要描述同一類型但數量不定的多個資料時,經常會使用一個前置的容器加若幹個連續的資料項的形式,這時稱這一系列連續的某一類型的資料為某一類型的集合。注意:class檔案中存儲的資料項都是被嚴格限定的,哪個位元組代表什麼含義,長度是多少,先後順序如何,都不允許改變。

Class檔案結構介紹[魔數版本号]
為了便于檢視class的結構我們通過一個java檔案編譯出對應的class檔案然後通過WinHex工具或者classpy來檢視。

public class Test {

    private int a;
    
    public int  run(){
        System.out.println("波波烤鴨");
        return a=1;
    }
}      

WinHex檢視class檔案:

Class檔案結構介紹[魔數版本号]

classPy檢視

Class檔案結構介紹[魔數版本号]

部分内容說明

1.魔數

Class檔案結構介紹[魔數版本号]

 每個Class檔案的頭4個位元組成為魔數(Magic Number),它的唯一作用是确定這個檔案是否為一個能被虛拟機接收的Class檔案。所有Class檔案,魔數均為0xCAFEBABE。

 注意:不僅僅是Class檔案,還有很多檔案(如:gif、jpeg等)都是以魔數(而不以字尾名)來進行身份識别的。

2.版本号

 緊接着魔數後的4個位元組是版本号,第5和第6是次版本号,第7和第8是主版本号。本文中使用的jdk版本是8是以版本資訊如下:

Class檔案結構介紹[魔數版本号]

 Class檔案能夠被版本号對應jdk版本(或比對應版本高)的jdk加載,不能被比對應jdk版本低的jdk加載。jdk中的版本号是從45開始的,每個jdk的target參數(如果有的話)的參數值對應一個主版本号

Class檔案結構介紹[魔數版本号]

參考《深入了解Java虛拟機》