成都java開發培訓
達內成都高升橋中心

成都java培訓機構:類文件結構

  • 時間:2021-01-07 16:12
  • 發布:成都達內
  • 來源:成都達內

1概述

我們知道,Java具有跨平臺性,其實現基礎就是虛擬機和字節碼存儲格式。Java虛擬機不與Java語言綁定,只與Class文件所關聯。Java虛擬機作為一個通用的、與機器無關的執行平臺,任何語言都可以將Java虛擬機作為它們的運行基礎,以Class文件作為它們產品的交付媒介。

Class文件是一組以8個字節為基礎單位的二進制流,各個數據項目嚴格按照順序緊湊地排列在文件之中,中間沒有添加任何分隔符,這使得整個Class文件中存儲的內容幾乎全部是程序運行的必要數據。當遇到需占用8個字節以上空間的數據項時,則會按照高位在前的方式分割成若干個 8 個字節進行存儲。

Class文件中有兩種數據類型,分別是無符合數和表:

無符號數屬于基本數據類型,以 u1、u2、u4、u8 來分別代表 1 個字節、2 個字節、4 個字節和 8 個字節的無符號數,無符號數可以用來描述數字、索引引用、數量值或UTF-8編碼構成字符串值

表是由多個無符號數或其他表作為數據項構成的復合數據類型,一般以 _info結尾。表用于描述有層次關系的復合結構的數據,整個Class文件本質上也可以視作是一張表

無論是無符號數還是表,當需要描述同一類型但數量不定的多個數據時,經常會使用一個前置的容量計數器加若干個連續的數據項的形式,這時候稱這一系列連續的某一類型的數據為某一類型的集合。

下面是 Class 文件格式:

<a style='color:blue' href='http://www.yingyicd.com/'>成都java培訓</a>機構:類文件結構

2魔數和 Class 文件版本Class 文件的頭 4 個字節被稱為魔數(Magic Number),它的唯一作用是確定該 Class 文件是否能被虛擬機接受,其值為 0xCAFEBABE(咖啡寶貝)。

緊接著魔數的 4 個字節存儲的是 Class 文件的版本號:第 5 和第 6 個字節是次版本號(Minor Version),第 7 和第 8 個字節是主版本號(Major Version)。Java 版本號從 45 開始,以后每個 JDK 大版本發布則主版本號加 1。高版本的 JDK 能向下兼容以前版本的 Class 文件,但不能運行以后版本的 Class 文件。

3|0常量池緊接著主、次版本號的是常量池入口,常量池入口需要放置一項 u2 類型的數據,代表常量池容量計數值(constant_pool_count),這個容量計數是從 1 而不是從 0 開始,第 0 項用于表達“不引用任何一個常量池項目”的含義。Class 文件結構中只有常量池的容量計數是從 1 開始,其他都是從 0 開始。

常量池中主要存放兩大類常量:字面量和符號引用。字面量比較接近 Java 語言層面的常量概念,如文本字符串、被聲明為 final 的常量值等。而符號引用則屬于編譯原理方面的概念,主要包括下面幾類常量:

被模塊導出或開放的包(Package)

類和接口的全限定名(Fully Qualified Name)

字段的名稱和描述符(Descriptor)

方法的名稱和描述符

方法句柄和方法類型(Method Handle、Method Type、Invoke Dynamic)

動態調用點和動態常量(Dynamically-Computed Call Site、Dynamically-Computed Constant)

Java 會在虛擬機加載 Class 文件的時候進行動態連接,將符號引用轉換為真正的內存入口。常量池中每一項常量都是一個表,最初有 11 種結構不同的表結構數據,后來為了更好地支持動態語言調用,額外增加了 4 種動態語言相關的常量,后來為了支持 Java 模塊化,又加入了 2 個常量,所以截止 JDK13,常量表中有 17 種不同類型的常量。這17類表都有一個共同的特點,表結構起始的第一位是個 u1 類型的標志位(tag)

17種常量類型所代表的具體含義如表:

成都java培訓機構:類文件結構

4訪問標志常量池結束之后,緊接著的 2 個字節代表訪問標志(access_flags),這個標志用于標識一些類或者接口層次的訪問信息,包括這個 Class 是類還是接口;是否定義為 public 類型;是否定義為 abstract 類型;如果是類的話,是否被聲明為 final 等等。具體的標志位以及標志的含義如表:

標志名稱標志值含義

成都java培訓機構:類文件結構

access_flags 中一共有 16 個標志位可以使用,當前只定義了其中 9 個,沒有使用到的標志位要求一律為零。

5類索引、父類索引與接口索引集合類索引(this_class)、父類索引(super_class)和接口索引(interfaces)都按順序排列在訪問標志之后,類索引和父類索引用兩個 u2 類型的索引值表示,而接口索引是一組 u2 類型的數據的集合。

類索引用于確定該類的全限定名,父類索引確定該類的父類的全限定名,由于 Java 不允許多繼承,因此父類索引只有一個,Object 類的父類索引為 0。類索引和父類索引各自指向一個 CONSTANT_Class_info 的類描述符常量,通過這個索引值可以找到定義在 CONSTANT_Utf8_info 類型的常量中的全限定名字符串。

對于接口索引集合,入口的第一項 u2 類型的數據為接口計數器(interfaces_count),表示索引表的容量,如果該類沒有實現任何接口,則該計數器的值為 0,后面接口的索引表不再占用任何字節。

6字段表集合方法表集合字段表集合(field_info)用于描述接口或類中聲明的變量,包括類級變量以及實例級變量,但不包括在方法內部聲明的局部變量。字段包含待信息有字段的作用域(public、private、protected)、是實例變量還是類變量(static)、可變性(final)等等。這些信息要么有,要么沒有,很適合用標志位來表示,而字段叫什么,被定義為什么數據類型,這些都無法固定,只能用常量池中的常量來描述。

字段表結構如下:

成都java培訓機構:類文件結構

access_flags 用來標識字段修飾符(public、static、final、volatile ...),name_index 和 descriptor_index 都是對常量池的引用,分別代表字段的簡單名稱以及字段和方法的描述符。之后的是屬性表集合,用于存儲一些額外信息。

字段表集合不會列出從父類或父接口繼承而來的字段,但有可能出現原本 Java 代碼中沒有的字段,例如內部類為了保持對外部類的訪問性,編譯器會自動添加指向外部類實例的字段。

方法表集合與字段表集合幾乎完全一致,僅在標志和屬性表集合的可選項中有所區別。至于方法里面的代碼,則經編譯后存放在方法屬性表集合中一個名為 Code 的屬性里面。

上一篇:成都java程序員學習:組合和繼承
下一篇:成都java培訓:Spring Boot Security國際化多語言 i18n

成都java培訓機構:java線程通信

成都java培訓學校:java死鎖

成都java培訓機構:線程守護(setDaemon)和線程同步

成都java培訓班:線程的狀態

  • 關注微信公眾號

    回復關鍵字:視頻資料

    免費領取 達內課程視頻學習資料

  • 視頻學習QQ群

    添加QQ群:1143617948

    免費領取達內課程視頻學習資料

Copyright ? 2018 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

選擇城市和中心
江西省

貴州省

廣西省

海南省

色综合AV社区男人的天堂