日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

首頁(yè) > 編程 > Java > 正文

實(shí)例分析Java Class的文件結(jié)構(gòu)

2019-11-26 16:12:51
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

學(xué)習(xí)Java的朋友應(yīng)該都知道Java從剛開(kāi)始的時(shí)候就打著平臺(tái)無(wú)關(guān)性的旗號(hào),說(shuō)“一次編寫(xiě),到處運(yùn)行”,其實(shí)說(shuō)到無(wú)關(guān)性,Java平臺(tái)還有另外一個(gè)無(wú)關(guān) 性那就是語(yǔ)言無(wú)關(guān)性,要實(shí)現(xiàn)語(yǔ)言無(wú)關(guān)性,那么Java體系中的class的文件結(jié)構(gòu)或者說(shuō)是字節(jié)碼就顯得相當(dāng)重要了,其實(shí)Java從剛開(kāi)始的時(shí)候就有兩套 規(guī)范,一個(gè)是Java語(yǔ)言規(guī)范,另外一個(gè)是Java虛擬機(jī)規(guī)范,Java語(yǔ)言規(guī)范只是規(guī)定了Java語(yǔ)言相關(guān)的約束以及規(guī)則,而虛擬機(jī)規(guī)范則才是真正從跨 平臺(tái)的角度去設(shè)計(jì)的。今天我們就以一個(gè)實(shí)際的例子來(lái)看看,到底Java中一個(gè)Class文件對(duì)應(yīng)的字節(jié)碼應(yīng)該是什么樣子。 這篇文章將首先總體上闡述一下Class到底由哪些內(nèi)容構(gòu)成,然后再用一個(gè)實(shí)際的Java類(lèi)入手去分析class的文件結(jié)構(gòu)。

在繼續(xù)之前,我們首先需要明確如下幾點(diǎn):

1)Class文件是有8個(gè)字節(jié)為基礎(chǔ)的字節(jié)流構(gòu)成的,這些字節(jié)流之間都嚴(yán)格按照規(guī)定的順序排列,并且字節(jié)之間不存在任何空隙,對(duì)于超過(guò)8個(gè)字節(jié)的數(shù)據(jù),將按 照Big-Endian的順序存儲(chǔ)的,也就是說(shuō)高位字節(jié)存儲(chǔ)在低的地址上面,而低位字節(jié)存儲(chǔ)到高地址上面,其實(shí)這也是class文件要跨平臺(tái)的關(guān)鍵,因?yàn)?PowerPC架構(gòu)的處理采用Big-Endian的存儲(chǔ)順序,而x86系列的處理器則采用Little-Endian的存儲(chǔ)順序,因此為了Class文 件在各中處理器架構(gòu)下保持統(tǒng)一的存儲(chǔ)順序,虛擬機(jī)規(guī)范必須對(duì)起進(jìn)行統(tǒng)一。

2) Class文件結(jié)構(gòu)采用類(lèi)似C語(yǔ)言的結(jié)構(gòu)體來(lái)存儲(chǔ)數(shù)據(jù)的,主要有兩類(lèi)數(shù)據(jù)項(xiàng),無(wú)符號(hào)數(shù)和表,無(wú)符號(hào)數(shù)用來(lái)表述數(shù)字,索引引用以及字符串等,比如 u1,u2,u4,u8分別代表1個(gè)字節(jié),2個(gè)字節(jié),4個(gè)字節(jié),8個(gè)字節(jié)的無(wú)符號(hào)數(shù),而表是有多個(gè)無(wú)符號(hào)數(shù)以及其它的表組成的復(fù)合結(jié)構(gòu)。可能大家看到這里 對(duì)無(wú)符號(hào)數(shù)和表到底是上面也不是很清楚,不過(guò)不要緊,等下面實(shí)例的時(shí)候,我會(huì)再以實(shí)例來(lái)解釋。

明確了上面的兩點(diǎn)以后,我們接下來(lái)后來(lái)看看Class文件中按照嚴(yán)格的順序排列的字節(jié)流都具體包含些什么數(shù)據(jù):

(上圖來(lái)自The Java Virtual Machine Specification Java SE 7 Edition)

在看上圖的時(shí)候,有一點(diǎn)我們需要注意,比如cp_info,cp_info表示常量池,上圖中用 constant_pool[constant_pool_count-1]的方式來(lái)表示常量池有constant_pool_count-1個(gè)常量,它 這里是采用數(shù)組的表現(xiàn)形式,但是大家不要誤以為所有的常量池的常量長(zhǎng)度都是一樣的,其實(shí)這個(gè)地方只是為了方便描述采用了數(shù)組的方式,但是這里并不像編程語(yǔ) 言那里,一個(gè)int型的數(shù)組,每個(gè)int長(zhǎng)度都一樣。明確了這一點(diǎn)以后,我們?cè)诨剡^(guò)頭來(lái)看看上圖中每一項(xiàng)都具體代表了什么含義。

1)u4 magic 表示魔數(shù),并且魔數(shù)占用了4個(gè)字節(jié),魔數(shù)到底是做什么的呢?它其實(shí)就是表示一下這個(gè)文件的類(lèi)型是一個(gè)Class文件,而不是一張JPG圖片,或者AVI的電影。而Class文件對(duì)應(yīng)的魔數(shù)是0xCAFEBABE.

2)u2 minor_version 表示Class文件的次版本號(hào),并且此版本號(hào)是u2類(lèi)型的無(wú)符號(hào)數(shù)表示。

3) u2 major_version 表示Class文件的主版本號(hào),并且主版本號(hào)是u2類(lèi)型的無(wú)符號(hào)數(shù)表示。major_version和minor_version主要用來(lái)表示當(dāng)前的虛擬 機(jī)是否接受當(dāng)前這種版本的Class文件。不同版本的Java編譯器編譯的Class文件對(duì)應(yīng)的版本是不一樣的。高版本的虛擬機(jī)支持低版本的編譯器編譯的 Class文件結(jié)構(gòu)。比如Java SE 6.0對(duì)應(yīng)的虛擬機(jī)支持Java SE 5.0的編譯器編譯的Class文件結(jié)構(gòu),反之則不行。

4) u2 constant_pool_count 表示常量池的數(shù)量。這里我們需要重點(diǎn)來(lái)說(shuō)一下常量池是什么東西,請(qǐng)大家不要與Jvm內(nèi)存模型中的運(yùn)行時(shí)常量池混淆了,Class文件中常量池主要存儲(chǔ)了字 面量以及符號(hào)引用,其中字面量主要包括字符串,final常量的值或者某個(gè)屬性的初始值等等,而符號(hào)引用主要存儲(chǔ)類(lèi)和接口的全限定名稱,字段的名稱以及描 述符,方法的名稱以及描述符,這里名稱可能大家都容易理解,至于描述符的概念,放到下面說(shuō)字段表以及方法表的時(shí)候再說(shuō)。另外大家都知道Jvm的內(nèi)存模型中 有堆,棧,方法區(qū),程序計(jì)數(shù)器構(gòu)成,而方法區(qū)中又存在一塊區(qū)域叫運(yùn)行時(shí)常量池,運(yùn)行時(shí)常量池中存放的東西其實(shí)也就是編譯器長(zhǎng)生的各種字面量以及符號(hào)引用, 只不過(guò)運(yùn)行時(shí)常量池具有動(dòng)態(tài)性,它可以在運(yùn)行的時(shí)候向其中增加其它的常量進(jìn)去,最具代表性的就是String的intern方法。

5)cp_info 表示常量池,這里面就存在了上面說(shuō)的各種各樣的字面量和符號(hào)引用。放到常量池的中數(shù)據(jù)項(xiàng)在The Java Virtual Machine Specification Java SE 7 Edition 中一共有14個(gè)常量,每一種常量都是一個(gè)表,并且每種常量都用一個(gè)公共的部分tag來(lái)表示是哪種類(lèi)型的常量。

下面分別簡(jiǎn)單描述一下具體細(xì)節(jié)等到后面的實(shí)例 中我們?cè)偌?xì)化。

CONSTANT_Utf8_info tag標(biāo)志位為1, UTF-8編碼的字符串CONSTANT_Integer_info tag標(biāo)志位為3, 整形字面量CONSTANT_Float_info tag標(biāo)志位為4, 浮點(diǎn)型字面量CONSTANT_Long_info tag標(biāo)志位為5, 長(zhǎng)整形字面量CONSTANT_Double_info tag標(biāo)志位為6, 雙精度字面量CONSTANT_Class_info tag標(biāo)志位為7, 類(lèi)或接口的符號(hào)引用CONSTANT_String_info tag標(biāo)志位為8,字符串類(lèi)型的字面量CONSTANT_Fieldref_info tag標(biāo)志位為9, 字段的符號(hào)引用CONSTANT_Methodref_info tag標(biāo)志位為10,類(lèi)中方法的符號(hào)引用CONSTANT_InterfaceMethodref_info tag標(biāo)志位為11, 接口中方法的符號(hào)引用CONSTANT_NameAndType_info tag 標(biāo)志位為12,字段和方法的名稱以及類(lèi)型的符號(hào)引用

6) u2 access_flags 表示類(lèi)或者接口的訪問(wèn)信息,具體如下圖所示:

7)u2 this_class 表示類(lèi)的常量池索引,指向常量池中CONSTANT_Class_info的常量

8)u2 super_class 表示超類(lèi)的索引,指向常量池中CONSTANT_Class_info的常量

9)u2 interface_counts 表示接口的數(shù)量

10)u2 interface[interface_counts]表示接口表,它里面每一項(xiàng)都指向常量池中CONSTANT_Class_info常量

11)u2 fields_count 表示類(lèi)的實(shí)例變量和類(lèi)變量的數(shù)量

12) field_info fields[fields_count]表示字段表的信息,其中字段表的結(jié)構(gòu)如下圖所示:

上圖中access_flags表示字段的訪問(wèn)表示,比如字段是public,private,protect 等,name_index表示字段名 稱,指向常量池中類(lèi)型是CONSTANT_UTF8_info的常量,descriptor_index表示字段的描述符,它也指向常量池中類(lèi)型為 CONSTANT_UTF8_info的常量,attributes_count表示字段表中的屬性表的數(shù)量,而屬性表是則是一種用與描述字段,方法以及 類(lèi)的屬性的可擴(kuò)展的結(jié)構(gòu),不同版本的Java虛擬機(jī)所支持的屬性表的數(shù)量是不同的。

13) u2 methods_count表示方法表的數(shù)量

14)method_info 表示方法表,方法表的具體結(jié)構(gòu)如下圖所示:


其中access_flags表示方法的訪問(wèn)表示,name_index表示名稱的索引,descriptor_index表示方法的描述 符,attributes_count以及attribute_info類(lèi)似字段表中的屬性表,只不過(guò)字段表和方法表中屬性表中的屬性是不同的,比如方法 表中就Code屬性,表示方法的代碼,而字段表中就沒(méi)有Code屬性。其中具體Class中到底有多少種屬性,等到Class文件結(jié)構(gòu)中的屬性表的時(shí)候再 說(shuō)說(shuō)。

15) attribute_count表示屬性表的數(shù)量,說(shuō)到屬性表,我們需要明確以下幾點(diǎn):

屬性表存在于Class文件結(jié)構(gòu)的最后,字段表,方法表以及Code屬性中,也就是說(shuō)屬性表中也可以存在屬性表屬性表的長(zhǎng)度是不固定的,不同的屬性,屬性表的長(zhǎng)度是不同的

上面說(shuō)完了Class文件結(jié)構(gòu)中每一項(xiàng)的構(gòu)成以后,我們以一個(gè)實(shí)際的例子來(lái)解釋以下上面所說(shuō)的內(nèi)容。

復(fù)制代碼 代碼如下:

package com.ejushang.TestClass;
public class TestClass implements Super{
private static final int staticVar = 0;
private int instanceVar=0;
public int instanceMethod(int param){
return param+1;
}
}
interface Super{ }

通過(guò)jdk1.6.0_37的javac 編譯后的TestClass.java對(duì)應(yīng)的TestClass.class的二進(jìn)制結(jié)構(gòu)如下圖所示:

下面我們就根據(jù)前面所說(shuō)的Class的文件結(jié)構(gòu)來(lái)解析以下上圖中字節(jié)流。

1)魔數(shù)
從Class的文件結(jié)構(gòu)我們知道,剛開(kāi)始的4個(gè)字節(jié)是魔數(shù),上圖中從地址00000000h-00000003h的內(nèi)容就是魔數(shù),從上圖可知Class的文件的魔數(shù)是0xCAFEBABE。

2)主次版本號(hào)
接下來(lái)的4個(gè)字節(jié)是主次版本號(hào),有上圖可知從00000004h-00000005h對(duì)應(yīng)的是0×0000,因此Class的minor_version 為0×0000,從00000006h-00000007h對(duì)應(yīng)的內(nèi)容為0×0032,因此Class文件的major_version版本為 0×0032,這正好就是jdk1.6.0不帶target參數(shù)編譯后的Class對(duì)應(yīng)的主次版本。

3)常量池的數(shù)量
接下來(lái)的2個(gè)字節(jié)從00000008h-00000009h表示常量池的數(shù)量,由上圖可以知道其值為0×0018,十進(jìn)制為24個(gè),但是對(duì)于常量池的數(shù)量 需要明確一點(diǎn),常量池的數(shù)量是constant_pool_count-1,為什么減一,是因?yàn)樗饕?表示class中的數(shù)據(jù)項(xiàng)不引用任何常量池中的常 量。

4)常量池
我們上面說(shuō)了常量池中有不同類(lèi)型的常量,下面就來(lái)看看TestClass.class的第一個(gè)常量,我們知道每個(gè)常量都有一個(gè)u1類(lèi)型的tag標(biāo)識(shí)來(lái)表示 常量的類(lèi)型,上圖中0000000ah處的內(nèi)容為0x0A,轉(zhuǎn)換成二級(jí)制是10,有上面的關(guān)于常量類(lèi)型的描述可知tag為10的常量是Constant_Methodref_info,而Constant_Methodref_info的結(jié)夠如下圖所示:

其中class_index指向常量池中類(lèi)型為CONSTANT_Class_info的常量,從TestClass的二進(jìn)制文件結(jié)構(gòu)中可以看出 class_index的值為0×0004(地址為0000000bh-0000000ch),也就是說(shuō)指向第四個(gè)常量。

name_and_type_index指向常量池中類(lèi)型為CONSTANT_NameAndType_info常量。從上圖可以看出name_and_type_index的值為0×0013,表示指向常量池中的第19個(gè)常量。

接下來(lái)又可以通過(guò)同樣的方法來(lái)找到常量池中的所有常量。不過(guò)JDK提供了一個(gè)方便的工具可以讓我們查看常量池中所包含的常量。通過(guò)javap -verbose TestClass 即可得到所有常量池中的常量,截圖如下:

從上圖我們可以清楚的看到,TestClass中常量池有24個(gè)常量,不要忘記了第0個(gè)常量,因?yàn)榈?個(gè)常量被用來(lái)表示 Class中的數(shù)據(jù)項(xiàng)不引用任何常量池中的常量。從上面的分析中我們得知TestClass的第一個(gè)常量表示方法,其中class_index指向的第四 個(gè)常量為java/lang/Object,name_and_type_index指向的第19個(gè)常量值為<init>:()V,從這里可 以看出第一個(gè)表示方法的常量表示的是java編譯器生成的實(shí)例構(gòu)造器方法。通過(guò)同樣的方法可以分析常量池的其它常量。OK,分析完常量池,我們接下來(lái)再分 析下access_flags。
5)u2 access_flags 表示類(lèi)或者接口方面的訪問(wèn)信息,比如Class表示的是類(lèi)還是接口,是否為public,static,final等。具體訪問(wèn)標(biāo)示的含義之前已經(jīng)說(shuō)過(guò) 了,下面我們就來(lái)看看TestClass的訪問(wèn)標(biāo)示。Class的訪問(wèn)標(biāo)示是從0000010dh-0000010e,期值為0×0021,根據(jù)前面說(shuō)的 各種訪問(wèn)標(biāo)示的標(biāo)志位,我們可以知道:0×0021=0×0001|0×0020 也即ACC_PUBLIC 和 ACC_SUPER為真,其中ACC_PUBLIC大家好理解,ACC_SUPER是jdk1.2之后編譯的類(lèi)都會(huì)帶有的標(biāo)志。

6)u2 this_class 表示類(lèi)的索引值,用來(lái)表示類(lèi)的全限定名稱,類(lèi)的索引值如下圖所示:

從上圖可以清楚到看到,類(lèi)索引值為0×0003,對(duì)應(yīng)常量池的第三個(gè)常量,通過(guò)javap的結(jié)果,我們知道第三個(gè)常量為 CONSTANT_Class_info類(lèi)型的常量,通過(guò)它可以知道類(lèi)的全限定名稱為:com/ejushang/TestClass /TestClass

7)u2 super_class 表示當(dāng)前類(lèi)的父類(lèi)的索引值,索引值所指向的常量池中類(lèi)型為CONSTANT_Class_info的常量,父類(lèi)的索引值如下圖所示,其值為0×0004, 查看常量池的第四個(gè)常量,可知TestClass的父類(lèi)的全限定名稱為:java/lang/Object

8)interfaces_count和 interfaces[interfaces_count]表示接口數(shù)量以及具體的每一個(gè)接口,TestClass的接口數(shù)量以及接口如下圖所示,其中 0×0001表示接口數(shù)量為1,而0×0005表示接口在常量池的索引值,找到常量池的第五個(gè)常量,其類(lèi)型為CONSTANT_Class_info,其 值為:com/ejushang/TestClass/Super

9)fields_count 和 field_info, fields_count表示類(lèi)中field_info表的數(shù)量,而field_info表示類(lèi)的實(shí)例變量和類(lèi)變量,這里需要注意的是 field_info不包含從父類(lèi)繼承過(guò)來(lái)的字段,field_info的結(jié)構(gòu)如下圖所示:

其中access_flags表示字段的訪問(wèn)標(biāo)示,比如public,private,protected,static,final等,access_flags的取值如下圖所示:

其中name_index 和 descriptor_index都是常量池的索引值,分別表示字段的名稱和字段的描述符,字段的名稱容易理解,但是字段的描述符如何理解呢?其實(shí)在JVM 規(guī)范中,對(duì)于字段的描述符規(guī)定如下圖所示:


其中大家需要關(guān)注一下上圖最后一行,它表示的是對(duì)一維數(shù)組的描述符,對(duì)于String[][]的描述符將是[[ Ljava/lang/String,而對(duì)于int[][]的描述符為[[I。接下來(lái)的attributes_count以及 attribute_info分別表示屬性表的數(shù)量以及屬性表。下面我們還是以上面的TestClass為例,來(lái)看看TestClass的字段表吧。

首先我們來(lái)看一下字段的數(shù)量,TestClass的字段的數(shù)量如下圖所示:

從上圖中可以看出TestClass有兩個(gè)字段,查看TestClass的源代碼可知,確實(shí)也只有兩個(gè)字段,接下來(lái)我們看看第一個(gè)字段,我們知道第一個(gè)字段應(yīng)該為private int staticVar,它在Class文件中的二進(jìn)制表示如下圖所示:


其中0x001A表示訪問(wèn)標(biāo)示,通過(guò)查看access_flags表可知,其為ACC_PRIVATE,ACC_STATIC,ACC_FINAL,接下 來(lái)0×0006和0×0007分別表示常量池中第6和第7個(gè)常量,通過(guò)查看常量池可知,其值分別為:staticVar和I,其中staticVar為字 段名稱,而I為字段的描述符,通過(guò)上面對(duì)描述符的解釋?zhuān)琁所描述的是int類(lèi)型的變量,接下來(lái)0×0001表示staticVar這個(gè)字段表中的屬性表的 數(shù)量,從上圖可以staticVar字段對(duì)應(yīng)的屬性表有1個(gè),0×0008表示常量池中的第8個(gè)常量,查看常量池可以得知此屬性為 ConstantValue屬性,而ConstantValue屬性的格式如下圖所示:

其中attribute_name_index表述屬性名的常量池索引,本例中為ConstantValue,而ConstantValue的 attribute_length固定長(zhǎng)度為2,而constantValue_index表示常量池中的引用,本例中,其中為0×0009,查看第9個(gè) 常量可以知道,它表示一個(gè)類(lèi)型為CONSTANT_Integer_info的常量,其值為0。

上面說(shuō)完了private static final int staticVar=0,下面我們接著說(shuō)一下TestClass的private int instanceVar=0,在本例中對(duì)instanceVar的二進(jìn)制表示如下圖所示:


其中0×0002表示訪問(wèn)標(biāo)示為ACC_PRIVATE,0x000A表示字段的名稱,它指向常量池中的第10個(gè)常量,查看常量池可以知道字段名稱為 instanceVar,而0×0007表示字段的描述符,它指向常量池中的第7個(gè)常量,查看常量池可以知道第7個(gè)常量為I,表示類(lèi)型為 instanceVar的類(lèi)型為I,最后0×0000表示屬性表的數(shù)量為0.

10)methods_count 和 method_info ,其中methods_count表示方法的數(shù)量,而method_info表示的方法表,其中方法表的結(jié)構(gòu)如下圖所示:

從上圖可以看出method_info和field_info的結(jié)構(gòu)是很類(lèi)似的,方法表的access_flag的所有標(biāo)志位以及取值如下圖所示:

其中name_index和descriptor_index表示的是方法的名稱和描述符,他們分別是指向常量池的索引。這里需要結(jié)解釋一下方法的描述 符,方法的描述符的結(jié)構(gòu)為:(參數(shù)列表)返回值,比如public int instanceMethod(int param)的描述符為:(I)I,表示帶有一個(gè)int類(lèi)型參數(shù)且返回值也為int類(lèi)型的方法,接下來(lái)就是屬性數(shù)量以及屬性表了,方法表和字段表雖然都有 屬性數(shù)量和屬性表,但是他們里面所包含的屬性是不同。接下來(lái)我們就以TestClass來(lái)看一下方法表的二進(jìn)制表示。首先來(lái)看一下方法表數(shù)量,截圖如下:


從上圖可以看出方法表的數(shù)量為0×0002表示有兩個(gè)方法,接下來(lái)我們來(lái)分析第一個(gè)方法,我們首先來(lái)看一下TestClass的第一個(gè)方法的access_flag,name_index,descriptor_index,截圖如下:


從上圖可以知道access_flags為0×0001,從上面對(duì)access_flags標(biāo)志位的描述,可知方法的access_flags的取值為 ACC_PUBLIC,name_index為0x000B,查看常量池中的第11個(gè)常量,知道方法的名稱為<init>,0x000C表示 descriptor_index表示常量池中的第12常量,其值為()V,表示<init>方法沒(méi)有參數(shù)和返回值,其實(shí)這是編譯器自動(dòng)生成 的實(shí)例構(gòu)造器方法。接下來(lái)的0×0001表示<init>方法的方法表有1個(gè)屬性,屬性截圖如下:

從上圖可以看出0x000D對(duì)應(yīng)的常量池中的常量為Code,表示的方法的Code屬性,所以到這里大家應(yīng)該明白方法的那些代碼是存儲(chǔ)在Class文件方法表中的屬性表中的Code屬性中。接下來(lái)我們?cè)诜治鲆幌翪ode屬性,Code屬性的結(jié)構(gòu)如下圖所示:

其中attribute_name_index指向常量池中值為Code的常量,attribute_length的長(zhǎng)度表示Code屬性表的長(zhǎng)度(這里 需要注意的時(shí)候長(zhǎng)度不包括attribute_name_index和attribute_length的6個(gè)字節(jié)的長(zhǎng)度)。

max_stack表示最大棧深度,虛擬機(jī)在運(yùn)行時(shí)根據(jù)這個(gè)值來(lái)分配棧幀中操作數(shù)的深度,而max_locals代表了局部變量表的存儲(chǔ)空間。

max_locals的單位為slot,slot是虛擬機(jī)為局部變量分配內(nèi)存的最小單元,在運(yùn)行時(shí),對(duì)于不超過(guò)32位類(lèi)型的數(shù)據(jù)類(lèi)型,比如 byte,char,int等占用1個(gè)slot,而double和Long這種64位的數(shù)據(jù)類(lèi)型則需要分配2個(gè)slot,另外max_locals的值并 不是所有局部變量所需要的內(nèi)存數(shù)量之和,因?yàn)閟lot是可以重用的,當(dāng)局部變量超過(guò)了它的作用域以后,局部變量所占用的slot就會(huì)被重用。

code_length代表了字節(jié)碼指令的數(shù)量,而code表示的時(shí)候字節(jié)碼指令,從上圖可以知道code的類(lèi)型為u1,一個(gè)u1類(lèi)型的取值為0×00-0xFF,對(duì)應(yīng)的十進(jìn)制為0-255,目前虛擬機(jī)規(guī)范已經(jīng)定義了200多條指令。

exception_table_length以及exception_table分別代表方法對(duì)應(yīng)的異常信息。

attributes_count和attribute_info分別表示了Code屬性中的屬性數(shù)量和屬性表,從這里可以看出Class的文件結(jié)構(gòu)中,屬性表是很靈活的,它可以存在于Class文件,方法表,字段表以及Code屬性中。

接下來(lái)我們繼續(xù)以上面的例子來(lái)分析一下,從上面init方法的Code屬性的截圖中可以看出,屬性表的長(zhǎng)度為0×00000026,max_stack的 值為0×0002,max_locals的取值為0×0001,code_length的長(zhǎng)度為0x0000000A,那么00000149h- 00000152h為字節(jié)碼,接下來(lái)exception_table_length的長(zhǎng)度為0×0000,而attribute_count的值為 0×0001,00000157h-00000158h的值為0x000E,它表示常量池中屬性的名稱,查看常量池得知第14個(gè)常量的值為 LineNumberTable,LineNumberTable用于描述java源代碼的行號(hào)和字節(jié)碼行號(hào)的對(duì)應(yīng)關(guān)系,它不是運(yùn)行時(shí)必需的屬性,如果通 過(guò)-g:none的編譯器參數(shù)來(lái)取消生成這項(xiàng)信息的話,最大的影響就是異常發(fā)生的時(shí)候,堆棧中不能顯示出出錯(cuò)的行號(hào),調(diào)試的時(shí)候也不能按照源代碼來(lái)設(shè)置斷 點(diǎn),接下來(lái)我們?cè)倏匆幌翷ineNumberTable的結(jié)構(gòu)如下圖所示:

其中attribute_name_index上面已經(jīng)提到過(guò),表示常量池的索引,attribute_length表示屬性長(zhǎng)度,而start_pc和 line_number分表表示字節(jié)碼的行號(hào)和源代碼的行號(hào)。本例中LineNumberTable屬性的字節(jié)流如下圖所示:

上面分析完了TestClass的第一個(gè)方法,通過(guò)同樣的方式我們可以分析出TestClass的第二個(gè)方法,截圖如下:

其中access_flags為0×0001,name_index為0x000F,descriptor_index為0×0010,通過(guò)查看常量池可 以知道此方法為public int instanceMethod(int param)方法。通過(guò)和上面類(lèi)似的方法我們可以知道instanceMethod的Code屬性為下圖所示:

最后我們來(lái)分析一下,Class文件的屬性,從00000191h-00000199h為Class文件中的屬性表,其中0×0011表示屬性的名稱,查看常量池可以知道屬性名稱為SourceFile,我們?cè)賮?lái)看看SourceFile的結(jié)構(gòu)如下圖所示:

其中attribute_length為屬性的長(zhǎng)度,sourcefile_index指向常量池中值為源代碼文件名稱的常量,在本例中SourceFile屬性截圖如下:


其中attribute_length為0×00000002表示長(zhǎng)度為2個(gè)字節(jié),而soucefile_index的值為0×0012,查看常量池的第18個(gè)常量可以知道源代碼文件的名稱為T(mén)estClass.java

最后,希望對(duì)技術(shù)感興趣的朋友多交流。個(gè)人微博:(http://weibo.com/xmuzyq)

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
欧美三级在线播放| 午夜成人鲁丝片午夜精品| 日韩精品视频中文在线观看| 亚洲欧洲国产视频| 国产三级在线| 国产91大片| 日韩亚洲一区中文字幕| 日韩精品在线私人| 99精品视频99| 欧洲精品久久久| 国产成人中文字幕| 91精品久久久久久久久| 中文在线不卡视频| 亚洲第一网中文字幕| 欧美在线视频二区| 日韩精品视频网| 91久久精品网| 国产一区在线精品| 国产视频2区| 欧洲精品在线一区| 蜜臀久久精品| 国产日韩在线亚洲字幕中文| 欧美不卡视频一区发布| 欧美日韩精品免费| 一区二区三区精品久久久| 国产传媒久久久| 91亚洲国产高清| 亚洲免费视频一区| 欧美三级精品| 日韩欧美99| 最近中文av字幕在线中文| 亚洲热线99精品视频| 日韩视频在线一区二区| 午夜伊人狠狠久久| 激情综合色综合久久| 亚洲免费看av| 亚洲一区在线视频观看| 亚洲热在线观看| 国产资源在线观看| 国产在线欧美日韩| 日韩精品视频在线播放| 日韩精品在线免费观看视频| 欧美日韩三级一区| 午夜成人鲁丝片午夜精品| 日韩欧美一级二级三级久久久| 中文字幕久精品免费视频| 国产日韩专区| 久草视频观看| 亚洲羞羞网站| 婷婷中文字幕一区三区| 欧美中文字幕第一页| 日韩视频一区在线观看| 国产在线视频一区二区| 亚洲成av人片在线| 欧美亚洲国产免费| 美女尤物久久精品| 偷窥国产亚洲免费视频| 日韩在线二区| 日韩欧美在线影院| 欧美在线视频第一页| 深夜福利一区| 日韩中文在线视频| 精品国产综合久久| 美女黄a一级视频| 欧美日韩精品免费看| 亚洲一区视频在线观看视频| 婷婷精品进入| 久久久精品网| 日韩精品手机在线观看| 日韩精品高清不卡| 日韩不卡在线播放| 婷婷综合福利| 一区视频在线播放| 日韩欧美字幕| 日韩欧美99| 欧美国产三级| 国产网站av| 国产在线精品日韩| 日韩国产91| 中文字幕线观看| 国产在线拍偷自揄拍精品| 92久久精品| 99久久婷婷| 伊人永久在线| 欧美不卡视频一区发布| 婷婷中文字幕综合| 欧美亚洲天堂| 久久99蜜桃精品久久久久小说| 欧美亚洲国产日韩| wwwww亚洲| 亚洲视频 中文字幕| 欧美日韩中文字幕| 欧美久久久久久蜜桃| 日本精品在线播放| 免费网站看黄yyy222| 欧美日韩国产一二三| 精品国产91乱高清在线观看| www.老鸭窝.com| 亚洲社区在线| 中文字幕在线观看亚洲| 美国av一区二区| 久久久久久久久99精品| 中文字幕五月欧美| 国产v日产∨综合v精品视频| 国产在线精品国自产拍免费| 日韩在线视频中文字幕| 欧美日韩在线视频免费观看| 免费精品国产自产拍观看| 中文国产字幕在线观看| 国产视频2区| 亚洲黄在线观看| 欧美 日韩 国产 高清| 日韩欧美在线综合网| 亚洲第一中文字幕在线观看| 日韩精品在线播放| 欧美日韩国产首页在线观看| 国产午夜精品视频| 国产福利久久| 日韩视频中文字幕| 欧美日韩在线国产| 91精品在线观看国产| 国产成人精品999| 中文字幕国产日韩| 在线手机中文字幕| 日韩三级视频在线| 欧美1区免费| 国产欧美日韩中文字幕| 日韩欧美国产片| 亚洲乱码视频| 91精品国产综合久久香蕉最新版| 国产高清精品二区| 婷婷中文字幕综合| 亚州福利视频| 精品日韩一区二区三区免费视频| 97最新国自产拍视频在线完整在线看| 精品欧美久久久| 久久久另类综合| 国产福利在线播放| 国产香蕉精品视频| 你懂的亚洲视频| 欧美日韩在线国产| 欧美三级网址| 欧美不卡123| 日本黄色一区二区| 在线视频一区二区三区在线播放| 亚洲欧美小说国产图片| 久久视频在线免费观看| 欧美三级中文字幕在线观看| 亚洲福利一区二区三区| 亚洲福利视频专区| 国产欧美日韩中文字幕| 国产欧美第一页| 国产一级片在线| 久久精品不卡| 麻豆一区二区99久久久久| 亚洲成年人在线播放| 国产日韩亚洲欧美| 亚洲国产欧美91| 国产不卡在线观看视频| 二区三区不卡不卡视频| 在线不卡日本| 欧美日韩国产在线| 91精品国产欧美日韩| av高清一区| 亚洲经典中文字幕| 日韩三级视频在线| 久久精品国产成人一区二区三区| 亚洲黄色一区二区| 久久精品蜜桃| 国产一级一片免费播放| 中文字幕一区二区三区精品| 一区二区高清视频| 国产欧美中文字幕| 国产欧美日韩中文字幕| 亚洲第一福利视频在线| 日韩视频中文| 国产成人精品av久久| 日韩高清不卡在线| 欧美日韩中文字幕在线| 中文字幕在线中文字幕二区| 亚洲免费观看视频| aaa大片在线观看| 欧美日韩亚洲视频| 国产又粗又猛又爽又黄91精品| 精品色蜜蜜精品视频在线观看| 日韩欧美不卡视频| 欧美三级三级三级爽爽爽| 欧美精品一区二区三区在线播放| 日韩免费不卡avV| 国产aa精品| 日韩欧美中文免费| 亚洲a一级视频| 欧美婷婷精品激情| 中文字幕在线播放一区| 国产不卡一区二区在线观看| av丝袜在线| 中文字幕在线观看亚洲| 日韩欧美久久久| 精品欧美久久久| 欧美一级欧美三级在线观看| 国产高清在线一区| 最近中文字幕在线中文高清版| 91精品国产91| 亚洲免费专区| 免费在线播放av| 一区二区91| av免费在线观看网址| 精品视频资源站| 欧美三级日本三级少妇99| 久久精品国产91精品亚洲| 欧美区高清在线| 99久久婷婷| av中文天堂在线| 中文字幕亚洲乱码| 欧美日韩国产第一页| 日韩精品高清不卡| 一区二区三区视频网站| 在线国产99| 亚洲羞羞网站| 欧美 日韩 综合| 欧美精品一区二区三区在线播放| 日韩欧美国产黄色| 中文字幕视频一区二区三区久| 久久视频在线免费观看| 日韩精品视频在线观看视频| 91精品国产乱码久久蜜臀| 久久精品最新免费国产成人| 日韩三级视频在线播放| 免费在线视频一级不卡| 在线资源av| 国产三级视频网站| 最近中文字幕第一页| 国产亚洲人成a一在线v站| 欧美综合精品| 国产日韩1区| 精品日韩av| 日韩不卡一区二区| 欧美日韩中文国产| 日韩三级在线播放| 亚洲免费婷婷| 亚洲欧美99| 亚洲成在线观看| 黄色片免费在线| 欧美日韩在线精品一区二区三区激情综| 欧美一级一级性生活免费录像| 亚洲社区在线| 国产乱国产乱老熟300部视频| 中文字幕在线观看视频www| 亚欧成人精品| 欧美亚洲另类制服自拍| 国产在线欧美| 丰满少妇一区| 中文字幕一区不卡| 91国内在线| 精产国产伦理一二三区| 大香一本蕉伊线亚洲网| 久草视频观看| 欧美xxxx中国| 精品在线一区二区| 精品成a人在线观看| 国产亚洲欧美色| 亚洲 欧美 日韩系列| 国产精品福利视频一区二区三区| 在线免费91| 天堂中文在线视频| 在线视频你懂得一区| 91久久久精品国产| av免费观看网站| 日韩欧美国产亚洲| 国产欧美日韩三级| 亚洲天堂国产视频| 久久精品视频免费看| 中文网丁香综合网| 国产一卡2卡3卡四卡网站| 中文字幕日韩免费视频| 天堂精品高清1区2区3区| 国产欧美综合视频| 91av久久久| 国产成人精品三级| 亚洲男人在线| 午夜国产欧美理论在线播放| 欧美日韩综合视频网址| 日韩 欧美 中文| 亚洲区中文字幕| 日韩影院二区| 精品熟女一区二区三区| 国产在线精品日韩| www.狠狠| 国产真实乱子伦精品视频| 国产v日产∨综合v精品视频| 亚洲区中文字幕| 日韩免费电影网站| 精品日韩视频在线观看| 日韩在线一区二区| 欧美成人精品在线| 人成在线免费视频| 欧美日韩国产高清一区| 亚洲成av人片| 在线中文字幕视频观看| 在线中文字幕网站| 国产中文伊人| 午夜一区二区视频| 日韩精品视频中文在线观看| 亚洲成在线观看| 国产不卡一区| av影视在线看| 日韩精品在线观看网站| 日韩欧美三级| 国产免费播放一区二区| 日韩免费精品视频| 一区二区三区精品久久久| 中文字幕精品在线视频| 中文字幕国产欧美| 亚洲一区在线观看免费| 精品精品久久| av免费观看国产| 日韩手机在线观看视频| 日韩你懂的电影在线观看| 国产99在线|亚洲| wwwwww国产| 日韩在线视频中文字幕| 久久精品国产视频| 亚洲一卡二卡在线观看| 午夜av一区二区| 日韩精品综合在线| 国产一区不卡精品| 国产丝袜欧美中文另类| 欧美日韩日本视频| 亚洲成年人在线播放| 91精品国产免费久久综合| 国产三级免费观看| 亚洲免费观看在线观看| 91久久精品国产91久久| 国产三级视频在线播放线观看| 日韩在线观看a| 91精品国产自产观看在线| 在线中文免费视频| 午夜伦欧美伦电影理论片| 国产xxx在线| 日韩欧美国产网站| 精品国产1区2区3区| 国产区日韩欧美| 亚洲免费精品视频| 亚洲乱码在线观看| 欧美亚洲天堂| 亚洲高清在线免费| 欧美日韩在线精品成人综合网| 91麻豆精品在线| 亚洲男人在线| 91精品国产91久久久久久青草| 在线观看免费国产成人软件| 久99久视频| 精品综合久久久久| 欧美日韩在线中文字幕| 日韩a一区二区| 中文在线视频观看| 日本精品在线| 久久99蜜桃精品| 欧美国产一级片| 日韩欧美中文在线| 国产一区不卡精品| 在线观看区一区二| 国产成人精品三级| 日韩免费不卡avV| 日韩欧美国产免费播放| 一区二区不卡视频| 欧美一卡2卡三卡4卡5免费| 黄色视屏免费在线观看| 国产成人一二三区| 国产最新在线| 日韩在线a电影| 国产区高清在线| 在线不卡日本| 在线视频色在线| 91精品久久久久久久久久入口| 欧美日韩视频免费播放| 国产字幕中文| 日本一级一片免费视频| 国产免费久久| 亚洲成年人影院在线| 国产视频中文字幕在线观看| 婷婷中文字幕在线观看| 国产福利一区在线观看| 精品999在线| 日韩国产亚洲欧美| 日韩中文字幕网| 樱花草www在线观看| 日韩精品中文字幕第1页| 国产视频一区三区| 精品一二三四| 亚洲视频在线观看三级| 婷婷久久综合九色国产成人| 亚洲素人一区二区| 国产在线观看精品| 欧美日韩在线不卡| 久久精品女人| 亚洲一区中文在线| xxxcom在线观看| 91精品国产丝袜白色高跟鞋| 黄色国产在线|