最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

類文件結構

2023-07-01 18:17 作者:全家桶激活  | 我要投稿

類文件結構

談論 JVM 的無關性,主要有以下兩個:

  • 平臺無關性:任何操作系統(tǒng)都能運行 Java 代碼

  • 語言無關性: JVM 能運行除 Java 以外的其他代碼

Java 源代碼首先需要使用 Javac 編譯器編譯成 .class 文件,然后由 JVM 執(zhí)行 .class 文件,從而程序開始運行。

JVM 只認識 .class 文件,它不關心是何種語言生成了 .class 文件,只要 .class 文件符合 JVM 的規(guī)范就能運行。 目前已經(jīng)有 JRuby、Jython、Scala 等語言能夠在 JVM 上運行。它們有各自的語法規(guī)則,不過它們的編譯器 都能將各自的源碼編譯成符合 JVM 規(guī)范的 .class 文件,從而能夠借助 JVM 運行它們。

Java 語言中的各種變量、關鍵字和運算符號的語義最終都是由多條字節(jié)碼命令組合而成的, 因此字節(jié)碼命令所能提供的語義描述能力肯定會比 Java 語言本身更加強大。 因此,有一些 Java 語言本身無法有效支持的語言特性,不代表字節(jié)碼本身無法有效支持。

Class 文件結構

Class 文件是二進制文件,它的內(nèi)容具有嚴格的規(guī)范,文件中沒有任何空格,全都是連續(xù)的 0/1。Class 文件 中的所有內(nèi)容被分為兩種類型:無符號數(shù)、表。

  • 無符號數(shù) 無符號數(shù)表示 Class 文件中的值,這些值沒有任何類型,但有不同的長度。u1、u2、u4、u8 分別代表 1/2/4/8 字節(jié)的無符號數(shù)。

  • 表 由多個無符號數(shù)或者其他表作為數(shù)據(jù)項構成的復合數(shù)據(jù)類型。

Class 文件具體由以下幾個構成:

  • 魔數(shù)

  • 版本信息

  • 常量池

  • 訪問標志

  • 類索引、父類索引、接口索引集合

  • 字段表集合

  • 方法表集合

  • 屬性表集合

魔數(shù)

Class 文件的頭 4 個字節(jié)稱為魔數(shù),用來表示這個 Class 文件的類型。

Class 文件的魔數(shù)是用 16 進制表示的“CAFE BABE”,是不是很具有浪漫色彩?

魔數(shù)相當于文件后綴名,只不過后綴名容易被修改,不安全,因此在 Class 文件中標識文件類型比較合適。

版本信息

緊接著魔數(shù)的 4 個字節(jié)是版本信息,5-6 字節(jié)表示次版本號,7-8 字節(jié)表示主版本號,它們表示當前 Class 文件中使用的是哪個版本的 JDK。

高版本的 JDK 能向下兼容以前版本的 Class 文件,但不能運行以后版本的 Class 文件,即使文件格式并未發(fā)生任何變化,虛擬機也必須拒絕執(zhí)行超過其版本號的 Class 文件。

常量池

版本信息之后就是常量池,常量池中存放兩種類型的常量:

  • 字面值常量

    字面值常量就是我們在程序中定義的字符串、被 final 修飾的值。

  • 符號引用

    符號引用就是我們定義的各種名字:類和接口的全限定名、字段的名字和描述符、方法的名字和描述符。

常量池的特點
  • 常量池中常量數(shù)量不固定,因此常量池開頭放置一個 u2 類型的無符號數(shù),用來存儲當前常量池的容量。

  • 常量池的每一項常量都是一個表,表開始的第一位是一個 u1 類型的標志位(tag),代表當前這個常量屬于哪種常量類型。

常量池中常量類型

類型tag描述 CONSTANT_utf8_info1UTF-8 編碼的字符串CONSTANT_Integer_info3整型字面量CONSTANT_Float_info4浮點型字面量CONSTANT_Long_info5長整型字面量CONSTANT_Double_info6雙精度浮點型字面量CONSTANT_Class_info7類或接口的符號引用CONSTANT_String_info8字符串類型字面量CONSTANT_Fieldref_info9字段的符號引用CONSTANT_Methodref_info10類中方法的符號引用CONSTANT_InterfaceMethodref_info11接口中方法的符號引用CONSTANT_NameAndType_info12字段或方法的符號引用CONSTANT_MethodHandle_info15表示方法句柄CONSTANT_MethodType_info16標識方法類型CONSTANT_InvokeDynamic_info18表示一個動態(tài)方法調(diào)用點

對于 CONSTANT_Class_info(此類型的常量代表一個類或者接口的符號引用),它的二維表結構如下:

類型名稱數(shù)量u1tag1u2name_index1

tag 是標志位,用于區(qū)分常量類型;name_index 是一個索引值,它指向常量池中一個 CONSTANT_Utf8_info 類型常量,此常量代表這個類(或接口)的全限定名,這里 name_index 值若為 0x0002,也即是指向了常量池中的第二項常量。

CONSTANT_Utf8_info 型常量的結構如下:

類型名稱數(shù)量u1tag1u2length1u1byteslength

tag 是當前常量的類型;length 表示這個字符串的長度;bytes 是這個字符串的內(nèi)容(采用縮略的 UTF8 編碼)

訪問標志

在常量池結束之后,緊接著的兩個字節(jié)代表訪問標志,這個標志用于識別一些類或者接口層次的訪問信息,包括:這個 Class 是類還是接口;是否定義為 public 類型;是否被 abstract/final 修飾。

類索引、父類索引、接口索引集合

類索引和父類索引都是一個 u2 類型的數(shù)據(jù),而接口索引集合是一組 u2 類型的數(shù)據(jù)的集合,Class 文件中由這三項數(shù)據(jù)來確定類的繼承關系。類索引用于確定這個類的全限定名,父類索引用于確定這個類的父類的全限定名。

由于 Java 不允許多重繼承,所以父類索引只有一個,除了 java.lang.Object 之外,所有的 Java 類都有父類,因此除了 java.lang.Object 外,所有 Java 類的父類索引都不為 0。一個類可能實現(xiàn)了多個接口,因此用接口索引集合來描述。這個集合第一項為 u2 類型的數(shù)據(jù),表示索引表的容量,接下來就是接口的名字索引。

類索引和父類索引用兩個 u2 類型的索引值表示,它們各自指向一個類型為 CONSTANT_Class_info 的類描述符常量,通過該常量總的索引值可以找到定義在 CONSTANT_Utf8_info 類型的常量中的全限定名字符串。

字段表集合

字段表集合存儲本類涉及到的成員變量,包括實例變量和類變量,但不包括方法中的局部變量。

每一個字段表只表示一個成員變量,本類中的所有成員變量構成了字段表集合。字段表結構如下:

類型名稱數(shù)量說明u2access_flags1字段的訪問標志,與類稍有不同u2name_index1字段名字的索引u2descriptor_index1描述符,用于描述字段的數(shù)據(jù)類型。 基本數(shù)據(jù)類型用大寫字母表示; 對象類型用“L 對象類型的全限定名”表示。u2attributes_count1屬性表集合的長度u2attributesattributes_count屬性表集合,用于存放屬性的額外信息,如屬性的值。

字段表集合中不會出現(xiàn)從父類(或接口)中繼承而來的字段,但有可能出現(xiàn)原本 Java 代碼中不存在的字段,譬如在內(nèi)部類中為了保持對外部類的訪問性,會自動添加指向外部類實例的字段。

方法表集合

方法表結構與屬性表類似。

volatile 關鍵字 和 transient 關鍵字不能修飾方法,所以方法表的訪問標志中沒有 ACC_VOLATILE 和 ACC_TRANSIENT 標志。

方法表的屬性表集合中有一張 Code 屬性表,用于存儲當前方法經(jīng)編譯器編譯后的字節(jié)碼指令。

屬性表集合

每個屬性對應一張屬性表,屬性表的結構如下:

類型名稱數(shù)量u2attribute_name_index1u4attribute_length1u1infoattribute_length



類文件結構的評論 (共 條)

分享到微博請遵守國家法律
锡林郭勒盟| 霸州市| 永昌县| 南投县| 安宁市| 南宁市| 义乌市| 黑龙江省| 栾城县| 广河县| 广元市| 钦州市| 永安市| 峨山| 周至县| 英山县| 清苑县| 长寿区| 建德市| 亚东县| 临邑县| 英吉沙县| 房产| 周口市| 红桥区| 宜阳县| 比如县| 满洲里市| 昌都县| 鹤庆县| 洛扎县| 通海县| 肃宁县| 股票| 丹东市| 阿荣旗| 长乐市| 化州市| 德江县| 普宁市| 博白县|