日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解 JVM Class文件格式(一)

發(fā)布時間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解 JVM Class文件格式(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

**

一、JVM體系結構

**

**

二、class格式文件概述

**

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

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

**

三、class文件詳細介紹

**

3.1 魔數(shù)

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

下面是一個class文件的二進制形式


3.2 主版本號和次版本號

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

如下圖,0034為主版本號,對應的十進制數(shù)為:50,查看下面圖,可知50對應的是JDK1.6,也就是說該class文件可被JDK1.6以上的虛擬機執(zhí)行

3.3 class文件中的常量池

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

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


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

JVM常量池中各數(shù)據(jù)項類型詳解,傳送門

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

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

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

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

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

class文件中的特殊字符串

class文件中的特殊字符串介紹見這里,傳送門

總結

以上是生活随笔為你收集整理的深入理解 JVM Class文件格式(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。