国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

JVM-class文件結構解析

2019-11-06 06:25:36
字體:
來源:轉載
供稿:網友
解析class文件的結構 魔數 + class文件次版本號 + class文件主版本號常量池訪問標志類索引,父類索引,接口索引字段表集合方法表集合屬性表集合

class文件是一組以8位字節為基礎單位的二進制流,緊密排列沒有分隔符。 class文件數據結構,包括兩種數據類型:無符號數無符號數:屬于基本的數據類型,u1,u2,u4,u8分別代表1個字節,2個字節,4個字節,8個字節。 :表是由多個無符號數或其他表作為數據項構成的符合數據類型,所有表都習慣性地以“_info”結尾。 這里寫圖片描述

1)魔數 + class文件次版本號 + class文件主版本號

魔數:前四個字節,為確定的0xCA FE BA BE。 class文件此版本號+class文件主版本號:第5,6與第7,8字節 這里寫圖片描述

2)常量池

第一個字節為常量池容量的計數值,計數從1開始,將第0項常量空出來是為了滿足后面某些指向常量池的索引值的數據在特定情況下需要表達“不引用任何一個常量池項目”的意思。例:該字節為0x0016,轉化為十進制為22,這就代表常量池有21項常量,索引值為1~21。

常量池之中主要存放兩大類常量:字面量符號引用字面量:比較接近于java語言的常量概念,如文本字符串,被聲明為final的常量值。 符號引用:屬于編譯原理方面的概念,包括:類和接口的全限定名 和 字段的名稱和描述符 和 方法的名稱和描述符。

常量池中每一項常量都是一個表,共有11種不同的常量數據結構表: 這里寫圖片描述 這里寫圖片描述 這里寫圖片描述

3)訪問標志

常量池結束之后,緊接著的2個字節代表訪問標志,這標志用于識別一些類或接口的層次的訪問信息,包括:這個Class是類還是接口;是否定義為public;是否為abstract類型;是否為final等等。 這里寫圖片描述 總共兩個字節16位可以使用,當前之定義了其中的8個

4)類索引,父類索引,接口索引

類索引與父類索引:用于確定這個類與父類的全限定名。各用一個u2類型常量池引用表示。 接口索引:入口第一項為u2類型的計數器,表示索引表的容量。若沒有接口則為0。若有則在后面通過相應數量的u2類型常量池引用表示。

5)字段表集合

字段表集合:用于描述接口或類中聲明的變量,包括類級變量與實例級變量,并不包含局部變量。 字段表結構:標志位,跟隨其后的是兩項索引值:name_index與descriptor_index。他們都是對常量池的引用,分別代表著字段的簡單名稱及字段和方法的描述符。(這里表示字段的類型,字段就是變量)。attributes_count,attribute_info表示屬性,后邊有介紹。 這里寫圖片描述

標志位:跟類的訪問標志相似。 這里寫圖片描述

描述符:是用來描述字段的數據類型,方法的參數列表和返回值。基本類型(byte,char,double,float,int,long,short,boolean)及void都是用一個大學字符來表示,而對象類型用字符L加對象的全限定名來表示。 這里寫圖片描述 對于數組如:java.lang.String[][] 表示為:”[[Ljava/lang/String;” 用描述符描述方法時:先參數后返回值:”int f(int i, char c, String[] ss)” 表示為:”(IC[Ljava/lang/String)I”

6)方法表集合

方法表結構與字段表結構一樣,但各項含義有所不同。 方法訪問標志也與字段訪問標志基本一致。 方法名有了,但方法中的代碼去哪了?方法里的代碼經過編譯器編譯成字節碼指令之后,存放在方法屬性表集合中一個名為“Code”的屬性里,屬性表作為Class文件格式中最具擴展行的一種數據項目,將在后邊詳解。

如果父類方法在子類中沒有被重寫,方法表集合中就不會出現來自父類的方法信息。有可能會出現來自編譯器自動添加的類構造器《clinit》方法與《init》方法,這兩個將在第十章說明。

7)屬性表集合

屬性表在前面的講解中出現過多次,在Class文件,字段表,方法表中都可以攜帶自己的屬性表集合,以用于描述某些場景專有的信息。 這里寫圖片描述

還有時間,接下來簡單學習一下各個屬性的含義:

① Code

這里寫圖片描述

attribute_name_index:是一項指向CONSTANT_Utf8_info型常量的索引,常量值固定位“COde”,他代表了該屬性的屬性名稱 attribute_length:指示了屬性值的長度,屬性值長度為屬性表長度減去attribute_name_index與attribute_length的長度(即減6)。 max_stack:代表了操作數棧深度的最大值。虛擬機運行的時候需要根據這個值來分配棧幀中的操作棧深度。 max_locals:局部變量表所需的存儲空間。單位為Slot。byte,char,float,int,short,boolean,reference,returnAddress占1個Slot。double,long占2個Slot。方法參數(包括this),顯示異常處理器的參數,內部局部變量都用該表存放。 code_length與code:用來存儲java源程序編譯后生成的字節碼指令。 exception_table_length與exception_table:用來執行遇到異常時的代碼跳轉處理。如下圖,一個try,catch,finally組合中的幾個跳轉。 這里寫圖片描述

② Exception屬性

表示方法可能拋出的異常,也就是方法描述時在throws關鍵字后面列舉的異常。

③ LineNumberTable屬性

java源碼行號與字節碼行號之間的對應關系。可有可無,會默認生成。沒有這項屬性的后果是拋出異常時將不會顯示出錯行號。

④ LocalVariableTable屬性

局部變量們的名稱,類型與生存周期,及在棧幀局部變量表中所占空間的位置。

問題:為什么沒有變量的初始化值?

這里寫圖片描述 這里寫圖片描述

⑤ SourceFIle屬性

記錄生成這個CLass文件的源碼文件的名稱。

⑥ ConstantValue屬性

作用是通知虛擬機自動為靜態變量賦值,只有static關鍵字修飾的變量才可以使用這項屬性。 對于非static類型的變量的賦值是在實例構造器《init》方法中進行的。而對于非static類型的變量的賦值是在類構造器《clinit》方法中進行的,或者使用ConstantValue屬性來賦值。目前編譯器的選擇是:如果同時使用final和static來修飾一個變量,并且這個變量的數據類型是基本類型或java.lang.Sring的話,就生成ConstantValue屬性來進行初始化,如果這個變量沒有被fianl修飾,或者并非基本類型及字符串,則選擇在《clinit》方法中就行初始化。

⑦ InnerClasses屬性

用于記錄內部類與宿主類之間的關聯。如果一個類中定義了內部類,那么編譯器將會為 它及其所包含的內部類 生成InnerClasses屬性。

問題: innerClass的代碼呢?

這里寫圖片描述 這里寫圖片描述


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 都兰县| 临泽县| 故城县| 祁东县| 安仁县| 资中县| 济源市| 禄丰县| 普格县| 双牌县| 安泽县| 玉屏| 筠连县| 花垣县| 宜城市| 苍南县| 南宁市| 开远市| 五大连池市| 枞阳县| 习水县| 望奎县| 崇信县| 错那县| 罗定市| 新建县| 宜章县| 绥芬河市| 兴城市| 故城县| 南靖县| 五台县| 贵定县| 日照市| 安新县| 永州市| 婺源县| 临泉县| 策勒县| 博兴县| 双鸭山市|