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

深入理解Java class文件格式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

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

Class文件在Java體系結(jié)構(gòu)中的位置和作用

對(duì)于理解JVM和深入理解Java語(yǔ)言, 學(xué)習(xí)并了解class文件的格式都是必須要掌握的功課。 原因很簡(jiǎn)單, JVM不會(huì)理解我們寫(xiě)的Java源文件, 我們必須把Java源文件編譯成class文件, 才能被JVM識(shí)別, 對(duì)于JVM而言, class文件相當(dāng)于一個(gè)接口, 理解了這個(gè)接口, 能幫助我們更好的理解JVM的行為;另一方面, class文件以另一種方式重新描述了我們?cè)谠次募幸磉_(dá)的意思, 理解class文件如何重新描述我們編寫(xiě)的源文件, 對(duì)于深入理解Java語(yǔ)言和語(yǔ)法都是很有幫助的。 另外, 不管是什么語(yǔ)言, 只要能編譯成class文件, 都能被JVM識(shí)別并執(zhí)行, 所以class文件不僅是跨平臺(tái)的基礎(chǔ), 也是JVM跨語(yǔ)言的基礎(chǔ), 理解了class文件格式, 對(duì)于我們學(xué)習(xí)基于JVM的其他語(yǔ)言會(huì)有很大幫助。 

總之, 在整個(gè)Java技術(shù)體系結(jié)構(gòu)中, class文件處于中間的位置, 對(duì)于理解整個(gè)體系有著承上啟下的作用。 如圖所示:

Class文件格式概述

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

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

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

類型
名稱
數(shù)量
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

下面對(duì)class文件中的每一項(xiàng)進(jìn)行詳細(xì)的解釋。

class文件中的魔數(shù)和版本號(hào)

(1) magic

在class文件開(kāi)頭的四個(gè)字節(jié), 存放著class文件的魔數(shù), 這個(gè)魔數(shù)是class文件的標(biāo)志,他是一個(gè)固定的值: 0XCAFEBABE 。 也就是說(shuō)他是判斷一個(gè)文件是不是class格式的文件的標(biāo)準(zhǔn), 如果開(kāi)頭四個(gè)字節(jié)不是0XCAFEBABE, 那么就說(shuō)明它不是class文件, 不能被JVM識(shí)別。

(2)minor_version 和 major_version

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

class文件中的常量池概述

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

class文件中的項(xiàng)constant_pool_count的值為1, 說(shuō)明每個(gè)類都只有一個(gè)常量池。 常量池中的數(shù)據(jù)也是一項(xiàng)一項(xiàng)的, 沒(méi)有間隙的依次排放。常量池中各個(gè)數(shù)據(jù)項(xiàng)通過(guò)索引來(lái)訪問(wèn), 有點(diǎn)類似與數(shù)組, 只不過(guò)常量池中的第一項(xiàng)的索引為1, 而不為0, 如果class文件中的其他地方引用了索引為0的常量池項(xiàng), 就說(shuō)明它不引用任何常量池項(xiàng)。class文件中的每一種數(shù)據(jù)項(xiàng)都有自己的類型, 相同的道理,常量池中的每一種數(shù)據(jù)項(xiàng)也有自己的類型。 常量池中的數(shù)據(jù)項(xiàng)的類型如下表:

常量池中數(shù)據(jù)項(xiàng)類型
類型標(biāo)志
類型描述
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
對(duì)一個(gè)類或接口的符號(hào)引用
CONSTANT_String
8
String類型字面值
CONSTANT_Fieldref
9
對(duì)一個(gè)字段的符號(hào)引用
CONSTANT_Methodref
10
對(duì)一個(gè)類中聲明的方法的符號(hào)引用
CONSTANT_InterfaceMethodref
11
對(duì)一個(gè)接口中聲明的方法的符號(hào)引用
CONSTANT_NameAndType
12
對(duì)一個(gè)字段或方法的部分符號(hào)引用

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

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

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

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

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

在詳細(xì)講解常量池中的各個(gè)數(shù)據(jù)項(xiàng)之前, 我們有必要先了解一下class文件中的特殊字符串, 因?yàn)樵诔A砍刂校?特殊字符串大量的出現(xiàn),這些特殊字符串就是上面說(shuō)的全限定名和描述符。 要理解常量池中的各個(gè)數(shù)據(jù)項(xiàng), 必須先了解這些特殊字符串。

相關(guān)文章

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

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

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

    Java監(jiān)聽(tīng)器三種實(shí)現(xiàn)方法代碼解析

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

    Java 圖表類庫(kù)詳解

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

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

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

    Java?Dubbo服務(wù)調(diào)用擴(kuò)展點(diǎn)Filter使用教程

    Dubbo是阿里巴巴公司開(kāi)源的一個(gè)高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過(guò)高性能的RPC實(shí)現(xiàn)服務(wù)的輸出和輸入功能,可以和Spring框架無(wú)縫集成
    2022-12-12
  • springboot在idea下debug調(diào)試熱部署問(wèn)題

    springboot在idea下debug調(diào)試熱部署問(wèn)題

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

    IDEA安裝lombok插件設(shè)置Enable Annotation Processing后編譯依然報(bào)錯(cuò)解決方法

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

    @JsonSerialize注解的使用示例教程

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

    Springboot項(xiàng)目長(zhǎng)時(shí)間不進(jìn)行接口操作,提示HikariPool-1警告的解決

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

    mybatis-flex實(shí)現(xiàn)多數(shù)據(jù)源操作

    MyBaits-Flex內(nèi)置了功能完善的多數(shù)據(jù)源支持,本文主要介紹了mybatis-flex實(shí)現(xiàn)多數(shù)據(jù)源操作,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06

最新評(píng)論