JVM知識總結--Class文件的構成(一)

.java文件通過javac編譯器編譯後會生成對應的.class文件,對java而言程序的執行都是在jvm中進行的,所以class文件的結構必然要知足jvm的標準;.class是格式嚴謹的二進制文件,沒有任何的空白符和分隔符,必須嚴格按照JVM標準排列;可使用javap -c命令反編譯獲得更易閱讀的字節碼文件html

class文件結構總覽

  1. 圖片第一列表示字段的類型,第二列是該字段的名稱;
  2. U二、U4分別表明2個字節、4個字節的無符號數;
  3. _info結尾的表明class文件中的,表也是由若干個無符號數和若干個表構成,用來表示複雜一些的class內容;
  4. 整個class文件就是一個大的表;

magic,minor_version,major_version

顧名思義,這三個字段分別存儲着class文件的魔數,class文件的副版本號和主版本號
值得一提的是magic字段的值自Oak時代就被肯定爲0XCAFEBABE,這也許就是爲何java和javaer都和咖啡有着深厚的不解之緣java

constant_pool_count,constant_pool[]

  1. constant_pool_count:表示接下來的常量池中常量的個數,但其值等於常量的個數+1
  2. constant_pool[]:從名稱能夠認爲常量池是一個近似數組的數據結構,數組中的每一個元素表明一個常量,該數組的下標爲1至constant_pool_count-1,總的來說常量池中的常量分爲兩類--字面量符號引用
    2.1. 字面量:對應java代碼中的字符串,聲明爲final的常量值等;
    2.2. 符號引用:包括類和接口的全限定名,字段的名稱和描述符,方法的名稱和描述符,jvm執行程序時,會根據這些符號信息進行解析和翻譯,在內存中找到對應的入口地址(相似C類語言的鏈接,但java發生在運行期);
  3. 常量池中的每個常量都是一個表,表的結構如cp_info {u1 tag;u1 info[];}
    3.1. tag:表示常量的類型,JAVA8有14種,JAVA11新增至17種,添加了CONSTANT_Dynamic(17|JAVA11)、CONSTANT_Module(19|JAVA9)、CONSTANT_Package(20|JAVA9)
    3.2. info:tag後的若干個字節,它們詳細表述了該常量的內容,下面簡要介紹幾個我的認爲比較典型的常量類型
    3.2.1. CONSTANT_Utf8_info:結構如u1 tag;u2 length;u1 bytes[length];,用來存儲全限定類名、方法名、字段名等,length字段使用了u2存儲,所以最大隻能爲65535Byte;
    3.2.2. CONSTANT_NameAndType_info:結構如u1 tag;u2 name_index;u2 descriptor_index;,其中name_index存儲的值爲一個CONSTANT_Utf8_info常量在常量池中的下標,該CONSTANT_Utf8_info表示了一個field或method的名稱,或<init>,descriptor_index存儲的值爲一個CONSTANT_Utf8_info常量在常量池中的下標,該CONSTANT_Utf8_info表示了一個field或method的描述符信息
    3.2.3. CONSTANT_Fieldref_info:結構如u1 tag;u2 class_index;u2 name_and_type_index;,用來存儲類的字段信息,其中class_index存儲的值表示一個CONSTANT_Class_info常量在常量池中的下標,該CONSTANT_Class_info存儲了此field所在類的類名信息,name_and_type_index存儲的值表示一個CONSTANT_NameAndType_info常量在常量池中的下標,該CONSTANT_NameAndType_info表示了此field的name和描述符信息,相似結構的還有CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info
    3.2.4. CONSTANT_MethodHandle_info:結構如u1 tag; u1 reference_kind; u2 reference_index;,其中reference_kind目前僅有1-9九個值,分別表明不一樣的methodHandle類型,不一樣值表明的含義能夠參考官方文檔,針對不一樣值的reference_kind,reference_index將分別指向CONSTANT_Fieldref_info或CONSTANT_Methodref_info或CONSTANT_InterfaceMethodref_info,用來對methodHandle的內容作更爲詳盡的描述;
    3.2.5. CONSTANT_Dynamic_info和CONSTANT_InvokeDynamic_info:與其餘常量不一樣,其餘常量表明的內容都被靜態記錄在常量池中,而這兩個常量帶表的內容由其中所記錄的引導方法(bootstrap method)動態生成,前者用來生成field,後者用來生成method,結構如u1 tag; u2 bootstrap_method_attr_index; u2name_and_type_index;,bootstrap_method_attr_index表示所使用的引導方法在class文件中的引導方法表中的下標,CONSTANT_NameAndType_info表示一個CONSTANT_NameAndType_info常量在常量池中的下標,該CONSTANT_NameAndType_info存儲着會動態生成的field或method的描述信息

access_flags

用來表示類或接口的訪問權限,以及內部元素的標誌信息,須要注意的是access_flags被定義爲掩碼,所以雖然使用的是u2類型,但僅有16個標誌位可使用,每一個access_flag僅在一個標誌位上爲1,其餘位所有爲0,目前定義了九個,分別用來標識public/final/super/interface/abstract/synthetic/annotation/enum/module,具體解釋能夠參考官方文檔bootstrap

參考

《深刻理解Java虛擬機》數組

Oracle JVMS數據結構

相關文章
相關標籤/搜索