首頁 > Java > java教程 > 主體

Java中class檔案格式的圖文詳解

黄舟
發布: 2017-06-18 09:45:32
原創
1860 人瀏覽過

對於理解JVM和深入理解Java語言, 學習並了解class檔案的格式都是必須要掌握的功課

Class檔案在Java架構中的位置和作用

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

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

Class檔案格式概述

class檔案是一種8位元組的二進位流文件, 各個資料項按順序緊密的從前向後排列, 相鄰的項之間沒有間隙, 這樣可以使得class文件非常緊湊, 體積輕巧, 可以被JVM快速的加載至內存,並且佔據較少的記憶體空間。 我們的Java原始文件, 在被編譯之後, 每個類別(或介面)都單獨佔據一個class文件, 並且類別中的所有資訊都會在class文件中有相應的描述, 由於class文件很靈活, 它甚至比Java原始檔有著更強的描述能力。

class檔案中的資訊是一項排列的, 每項資料都有它的固定長度, 有的佔一個字節, 有的佔兩個字節, 還有的佔四個位元組或8個位元組, 資料項的不同長度分別以u1, u2, u4, u8表示, 分別表示一種資料項在class檔案中佔據一個字節, 兩個字節,4個位元組和8個位元組。 可以把u1, u2, u3, u4看做class檔案資料項的「型別」 。

class檔案中存在以下資料項目(此圖表參考自《深入Java虛擬機器》):

##this_class#u2methods

#類型

名稱

數量

u4

magic

1

u2

次要版本

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

# ##super_class###################1#######

u2

#interfaces_count

1

u2

介面

interfaces_count

u2

########### # ############fields_count###################1################################1################# # #######field_info##################欄位######

fields_count

#u2

methods_count

1

##1

## method_info

##methods_count

######## ##### ############u2###################attribute_count############## ##### #1########################attribute_info#######

屬性

#attributes_count

################################################################################################################ #


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

class檔案中的魔數與版本號

#(1) magic

在class檔案開頭的四個位元組, 存放著class檔案的魔數, 這個魔數是class檔案的標誌,他是固定的值: 0XCAFEBABE 。 也就是說他是判斷一個文件是不是class格式的文件的標準, 如果開頭四個位元組不是0XCAFEBABE, 那就表示它不是class文件, 就不能被JVM辨識。

(2)minor_version 和 major_version

緊接著魔數的四個位元組是class檔案的此版本號碼和主版本號。 隨著Java的發展, class檔案的格式也會做相對應的變動。 版本號碼標誌著class檔案在什麼時候, 加入或改​​變了哪些特性。 舉例來說, 不同版本的javac編譯器編譯的class文件, 版本號碼可能不同, 而不同版本的JVM能辨識的class文件的版本號碼也可能不同, 一般情況下,高版本的JVM能辨識低版本的javac編譯器編譯的class文件,而低版本的JVM不能辨識高版本的javac編譯器編譯的class檔。 如果使用低版本的JVM執行高版本的class文件, JVM會拋出java.lang.UnsupportedClassVersionError 。具體的版本號變遷這裡不再討論, 需要的讀者自行查閱資料。

class檔案中的常數池概述

#在class檔案中, 位於版本號碼後面的就是常數池相關的數據項。 常量池是class檔案中非常重要的資料。 常量池中存放了文字字串, 常數值, 目前類別的類別名, 欄位名, 方法名, 各個欄位和方法的描述符, 對目前類別的欄位和方法的參考訊息, 當前類別中對其他類別的引用資訊等等。常量池中幾乎包含類別中的所有資訊的描述, class檔案中的許多其他部分都是對常數池中的資料項目的引用,例如後面要講到的this_class, super_class, field_info, attribute_info等, 另外位元組碼指令中也存在對常數池的引用, 這個對常數池的引用當做字節碼指令的一個操作數。  此外, 常量池中各項也會互相引用。

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

#double類型字面值## CONSTANT_Class7#對一個類別或介面的符號引用

#常數池中資料項目類型

型別標誌

型別描述

CONSTANT_Utf8

1

UTF-8編碼的Unicode字串

CONSTANT_Integer

3

#int型別字面上值

CONSTANT_Float

4

#float類型字面值

#CONSTANT_Long

5

#long類型字面上值

#CONSTANT_Double

6

##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程式是動態連結的, 在動態連結的實作中, 常數池扮演者舉足輕重的角色。 除了存放一些字面量之外, 常數池中還存放著以下幾種符號引用:

(1) 類別和介面的全限定名

(2 ) 欄位的名稱和描述符

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

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

以上是Java中class檔案格式的圖文詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板