JVM--Class類文件

Class類文件:

  1. Class類文件是以一組8個字節爲基礎單位的二進制字節流
  2. 各個數據項目按照順序整齊的排列於文件中,中間沒有任何分隔符,每個數據項都是運行時必要數據,不允許修改
  3. 如果遇到需要8個字節以上的數據項需要存儲時,則會按高位在前的方式將其劃分成若干個8字節進行存儲
  4. Class類文件採用C語言結構體的僞結構來存儲數據,僞結構共有兩種數據類型:無符號數,表
    1. 無符號數:屬於基本的數據類型,以u1,u2,u4,u8來代表一個字節、二個字節、四個字節、八個字節的無符號數;可以用來描述數值,索引引用,數量值以及按照UTF-8格式編碼的字符串值
    2. 表:可以由多個符號數或者其他表構成數據項從而形成複合類型數據;爲了便於區分,表名以“_info”結尾。可以用來描述具有層次關係的複合類型數據;Class文件本質上就可以看成是一個表

Class文件中的8個字節:

  1. Class文件中的頭四個字節爲魔數
  2. 魔數:唯一作用就是判定該文件是否是一個能被虛擬機認可的class文件
  3. 後四個字節爲版本號,第5,6個爲次版本號;第7,8個爲主版本號

常量池:

  1. 緊挨着主次版本號之後的就是常量池的入口
  2. 常量池被譽爲class文件中的資源倉庫
  3. 他是class文件中與其他項目交流最多的數據項,也是佔用class文件空間最大的數據項之一
  4. 常量池是class文件中出現的第一個表結構的數據類型
  5. 常量池中的常量個數時不穩定的,需要設置常量池容量計數值
  6. 常量池主要是用於存儲:字面量以及符號引用

字面量和符號引用:

  1. 字面量:屬於JAVA語言層次的常量概念,可以用來描述文本字符串值或者被final修飾的常量等等
  2. 符號引用:屬於編譯原理方面的概念,可以用來描述以下常量:
    1. 被模塊導出的、開放的包(package)
    2. 類和接口的全限定名
    3. 字段的名稱和描述符
    4. 方法的名稱和描述符
    5. 方法句柄和方法類型
    6. 動態調用點和動態變量

訪問標誌:

  1. 緊挨着常量池之後的兩個字節就是訪問標誌,標誌着一些類和接口層次的訪問信息,比如
    1. 該class文件是類還是接口
    2. 是否被聲明爲public類型
    3. 是否被聲明爲abstract類型
    4. 如果是類是否被聲明爲final等等

類索引、父類索引、接口索引集合:

  1. 類索引、父類索引以及接口索引集合按照順序排列於訪問標誌之後
  2. 類索引和父類索引是一個u2類型的數據,接口索引集合是一組u2類型數據的集合,Class文件中的這三項數據用於確定該類型的繼承關係
  3. 其中類索引用於確定該類的全限定名;父類索引用於確定該類父類的全限定名;java中不允許多繼承所以最多只能有一個父類索引;出來java.lang.Object沒有父類之外,其他的父類索引都不應該是0
  4. 接口索引集合是用來描述實現了哪些接口,將實現了的接口在implements關鍵字之後按照從左到右的順序排列在接口索引集合中(如果是接口則換成extends關鍵字)

字段表集合:

  1. 字段表集合用來描述類變量以及實例變量。java中的字段包括類變量和實例變量,但不包括方法內部的局部變量。
  2. 字段表集合中不會出現父類或者接口中的字段,但可能會出現代碼中不存在的字段,比如內部類爲了保持對外部類的訪問性,編譯器會自動添加指向外部類實例的字段
  3. java中不允許字段的重載,無論是簡單名稱相同還是數據類型相同,都不能對字段進行重載;class文件中只要描述符不一樣,字段重載就是合法的

字段:

  1. 字段中包括描述字段的修飾符:字段的作用域(public private protected修飾符)、是類變量還是實例變量(static修飾符)、可變性(final修飾符)、併發可見性(volatile修飾符,是否強制從主內存中讀寫)、是否序列化(transient修飾符)以及字段的數據類型(基本數據類型、對象、數組等)以及方法名稱

全限定名,簡單名稱,方法和字段的描述符:

  1. 全限定名:把類全名中的“.”替換爲“/”,爲了避免多個全限定名混淆,會以“;”結尾
  2. 簡單名稱:不用任何修飾符和類型來描述的方法和字段,比如類中的inter()方法和master字段,他們的簡單名稱就是inter,master
  3. 描述符:用來描述字段的數據類型,方法的參數列表(數量、順序以及類型)和返回值;其中基本數據類型和無返回值void類型用一個大寫字符來表示;對象的話需要一個大寫字符L和他的全限定名來表示

方法表集合:

  1. 方法表集合和字段表集合的結構是一樣的,依次包括訪問標誌、名稱索引、描述符索引以及屬性表集合;其中與字段表集合不同的是訪問標誌和屬性表集合的一些可選項
  2. 比如transient和volatile關鍵字是不能用來修飾方法的,所以方法表集合中不會出現與其對應的訪問標誌:ACC_TRANSIENT以及ACC_VOLATILE
  3. synchronized、native、stractfp、abstract關鍵字可以用來修飾方法,方法表集合中也必定會出現和他們一一對應的訪問標誌
  4. 可字段表集合一樣,方法表集合中同樣不會出現沒有從父類或者接口重寫來的方法,同樣會出現代碼中不存在的方法,比如類構造器<client>()方法以及實例構造器<init>()方法
  5. java中方法的重載:可以允許簡單名稱相同,特徵簽名不同即可,但無法僅僅通過返回值不同來對方法進行重載;class中只要特徵簽名不一樣就可以重載(比如簡單名稱,特徵簽名相同,返回值不同也是合法的)

特徵簽名:

  1. 特徵簽名就是一個方法中所需的所有參數在常量池中的字段的符號引用的集合;包括方法名稱、參數數量、參數類型順序的等,唯獨不包含返回值

屬性表集合:

  1. 用於存放虛擬機自己實現的屬性,屬性名稱不能相同,java虛擬機會忽略自己不認識的屬性

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章