欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解Java class文件格式_動力節(jié)點Java學院整理

 更新時間:2017年06月16日 10:42:28   作者:zhangjg  
對于理解JVM和深入理解Java語言, 學習并了解class文件的格式都是必須要掌握的功課

Class文件在Java體系結構中的位置和作用

對于理解JVM和深入理解Java語言, 學習并了解class文件的格式都是必須要掌握的功課。 原因很簡單, JVM不會理解我們寫的Java源文件, 我們必須把Java源文件編譯成class文件, 才能被JVM識別, 對于JVM而言, class文件相當于一個接口, 理解了這個接口, 能幫助我們更好的理解JVM的行為;另一方面, class文件以另一種方式重新描述了我們在源文件中要表達的意思, 理解class文件如何重新描述我們編寫的源文件, 對于深入理解Java語言和語法都是很有幫助的。 另外, 不管是什么語言, 只要能編譯成class文件, 都能被JVM識別并執(zhí)行, 所以class文件不僅是跨平臺的基礎, 也是JVM跨語言的基礎, 理解了class文件格式, 對于我們學習基于JVM的其他語言會有很大幫助。 

總之, 在整個Java技術體系結構中, class文件處于中間的位置, 對于理解整個體系有著承上啟下的作用。 如圖所示:

Class文件格式概述

class文件是一種8位字節(jié)的二進制流文件, 各個數據項按順序緊密的從前向后排列, 相鄰的項之間沒有間隙, 這樣可以使得class文件非常緊湊, 體積輕巧, 可以被JVM快速的加載至內存, 并且占據較少的內存空間。 我們的Java源文件, 在被編譯之后, 每個類(或者接口)都單獨占據一個class文件, 并且類中的所有信息都會在class文件中有相應的描述, 由于class文件很靈活, 它甚至比Java源文件有著更強的描述能力。

class文件中的信息是一項一項排列的, 每項數據都有它的固定長度, 有的占一個字節(jié), 有的占兩個字節(jié), 還有的占四個字節(jié)或8個字節(jié), 數據項的不同長度分別用u1, u2, u4, u8表示, 分別表示一種數據項在class文件中占據一個字節(jié), 兩個字節(jié), 4個字節(jié)和8個字節(jié)。 可以把u1, u2, u3, u4看做class文件數據項的“類型” 。

class文件中存在以下數據項(該圖表參考自《深入Java虛擬機》):

類型
名稱
數量
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
access_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
attribute_count
1
attribute_info
attributes
attributes_count

下面對class文件中的每一項進行詳細的解釋。

class文件中的魔數和版本號

(1) magic

在class文件開頭的四個字節(jié), 存放著class文件的魔數, 這個魔數是class文件的標志,他是一個固定的值: 0XCAFEBABE 。 也就是說他是判斷一個文件是不是class格式的文件的標準, 如果開頭四個字節(jié)不是0XCAFEBABE, 那么就說明它不是class文件, 不能被JVM識別。

(2)minor_version 和 major_version

緊接著魔數的四個字節(jié)是class文件的此版本號和主版本號。 隨著Java的發(fā)展, class文件的格式也會做相應的變動。 版本號標志著class文件在什么時候, 加入或改變了哪些特性。 舉例來說, 不同版本的javac編譯器編譯的class文件, 版本號可能不同, 而不同版本的JVM能識別的class文件的版本號也可能不同, 一般情況下, 高版本的JVM能識別低版本的javac編譯器編譯的class文件, 而低版本的JVM不能識別高版本的javac編譯器編譯的class文件。 如果使用低版本的JVM執(zhí)行高版本的class文件, JVM會拋出java.lang.UnsupportedClassVersionError 。具體的版本號變遷這里不再討論, 需要的讀者自行查閱資料。 

class文件中的常量池概述

在class文件中, 位于版本號后面的就是常量池相關的數據項。 常量池是class文件中的一項非常重要的數據。 常量池中存放了文字字符串, 常量值, 當前類的類名, 字段名, 方法名, 各個字段和方法的描述符, 對當前類的字段和方法的引用信息, 當前類中對其他類的引用信息等等。 常量池中幾乎包含類中的所有信息的描述, class文件中的很多其他部分都是對常量池中的數據項的引用,比如后面要講到的this_class, super_class, field_info, attribute_info等, 另外字節(jié)碼指令中也存在對常量池的引用, 這個對常量池的引用當做字節(jié)碼指令的一個操作數。  此外, 常量池中各個項也會相互引用。

class文件中的項constant_pool_count的值為1, 說明每個類都只有一個常量池。 常量池中的數據也是一項一項的, 沒有間隙的依次排放。常量池中各個數據項通過索引來訪問, 有點類似與數組, 只不過常量池中的第一項的索引為1, 而不為0, 如果class文件中的其他地方引用了索引為0的常量池項, 就說明它不引用任何常量池項。class文件中的每一種數據項都有自己的類型, 相同的道理,常量池中的每一種數據項也有自己的類型。 常量池中的數據項的類型如下表:

常量池中數據項類型
類型標志
類型描述
CONSTANT_Utf8
1
UTF-8編碼的Unicode字符串
CONSTANT_Integer
3
int類型字面值
CONSTANT_Float
4
float類型字面值
CONSTANT_Long
5
long類型字面值
CONSTANT_Double
6
double類型字面值
CONSTANT_Class
7
對一個類或接口的符號引用
CONSTANT_String
8
String類型字面值
CONSTANT_Fieldref
9
對一個字段的符號引用
CONSTANT_Methodref
10
對一個類中聲明的方法的符號引用
CONSTANT_InterfaceMethodref
11
對一個接口中聲明的方法的符號引用
CONSTANT_NameAndType
12
對一個字段或方法的部分符號引用

每個數據項叫做一個XXX_info項, 比如, 一個常量池中一個CONSTANT_Utf8類型的項, 就是一個CONSTANT_Utf8_info 。除此之外, 每個info項中都有一個標志值(tag), 這個標志值表明了這個常量池中的info項的類型是什么, 從上面的表格中可以看出, 一個CONSTANT_Utf8_info中的tag值為1, 而一個CONSTANT_Fieldref_info中的tag值為9 。

Java程序是動態(tài)鏈接的, 在動態(tài)鏈接的實現中, 常量池扮演者舉足輕重的角色。 除了存放一些字面量之外, 常量池中還存放著以下幾種符號引用:

(1) 類和接口的全限定名

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

(3) 方法的名稱和描述符

在詳細講解常量池中的各個數據項之前, 我們有必要先了解一下class文件中的特殊字符串, 因為在常量池中, 特殊字符串大量的出現,這些特殊字符串就是上面說的全限定名和描述符。 要理解常量池中的各個數據項, 必須先了解這些特殊字符串。

相關文章

  • Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    spring Boot默認就是使用thymeleaf模板引擎的,下面這篇文章主要給大家介紹了關于在Spring Boot中利用Thymeleaf發(fā)送Email的方法教程,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-08-08
  • Java監(jiān)聽器三種實現方法代碼解析

    Java監(jiān)聽器三種實現方法代碼解析

    這篇文章主要介紹了Java監(jiān)聽器三種實現方法代碼解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Java 圖表類庫詳解

    Java 圖表類庫詳解

    本文主要介紹了Java圖表類庫的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • springboot 打包部署 共享依賴包(分布式開發(fā)集中式部署微服務)

    springboot 打包部署 共享依賴包(分布式開發(fā)集中式部署微服務)

    這篇文章主要介紹了springboot 打包部署 共享依賴包(分布式開發(fā)集中式部署微服務)的相關資料,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-06-06
  • Java?Dubbo服務調用擴展點Filter使用教程

    Java?Dubbo服務調用擴展點Filter使用教程

    Dubbo是阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架,使得應用可通過高性能的RPC實現服務的輸出和輸入功能,可以和Spring框架無縫集成
    2022-12-12
  • springboot在idea下debug調試熱部署問題

    springboot在idea下debug調試熱部署問題

    這篇文章主要介紹了springboot在idea下debug調試熱部署問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • IDEA安裝lombok插件設置Enable Annotation Processing后編譯依然報錯解決方法

    IDEA安裝lombok插件設置Enable Annotation Processing后編譯依然報錯解決方法

    這篇文章主要介紹了IDEA安裝lombok插件設置Enable Annotation Processing后編譯依然報錯解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • @JsonSerialize注解的使用示例教程

    @JsonSerialize注解的使用示例教程

    在開發(fā)中,有時候某些字段需要特殊處理,比如我們有一個日期字段,當日期為NULL時給前端不返回NULL而返回為其他等信息,就需要自定義字段的序列化,這就是@JsonSerialize的用處,本文給大家介紹@JsonSerialize注解的使用,感興趣的朋友一起看看吧
    2023-11-11
  • Springboot項目長時間不進行接口操作,提示HikariPool-1警告的解決

    Springboot項目長時間不進行接口操作,提示HikariPool-1警告的解決

    這篇文章主要介紹了Springboot項目長時間不進行接口操作,提示HikariPool-1警告的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • mybatis-flex實現多數據源操作

    mybatis-flex實現多數據源操作

    MyBaits-Flex內置了功能完善的多數據源支持,本文主要介紹了mybatis-flex實現多數據源操作,具有一定的參考價值,感興趣的可以了解一下
    2024-06-06

最新評論