資源描述:
《Java虛擬機(jī)的Class文件結(jié)構(gòu)詳解.doc》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、深入JVM的Class文件結(jié)構(gòu)Class文件由順序的8位字節(jié)為基礎(chǔ)單位構(gòu)成的二進(jìn)制流。各個(gè)項(xiàng)目嚴(yán)格按照順序緊湊排列,無分隔符。需要用8位字節(jié)以上空間數(shù)據(jù)項(xiàng)時(shí)按照高位在前分割成若干個(gè)8位字節(jié)存儲(chǔ)。只包含2種數(shù)據(jù)類型:·無符號(hào)數(shù)·表無符號(hào)數(shù)是class文件基本數(shù)據(jù)類型,以u1,u2,u4,u8分別代表1個(gè)字節(jié),2個(gè),4個(gè),8個(gè)字節(jié)的無符號(hào)數(shù)。可以用來描述數(shù)字、索引引用、數(shù)量值、以UTF—8編碼構(gòu)成的字符串.表由多個(gè)無符號(hào)數(shù)或其他表作為數(shù)據(jù)項(xiàng)構(gòu)成的復(fù)合數(shù)據(jù)類型。所有表以“_info”結(jié)尾。用來描述具有層
2、次關(guān)系的復(fù)合結(jié)構(gòu)數(shù)據(jù)。其實(shí)class文件本質(zhì)上就是一張表。Class文件結(jié)構(gòu)包含magic魔數(shù),文件版本,常量池,訪問標(biāo)識(shí),類索引、父類索引與接口索引集合,字段表集合,方法表集合,屬性表集合等構(gòu)成魔數(shù)在class文件頭4個(gè)字節(jié),magicnumber.作用:確定該文件是否是虛擬機(jī)可接受的class文件.java的魔數(shù)統(tǒng)一為0xCAFEBABE(來源于一款咖啡).版本號(hào)由minorversion和majorversion組成,占用文件中第5到8字節(jié).如CAFE BABE00000032表示此版本號(hào)為
3、50.0,十進(jìn)制表示一般格式為major.minor?需要注意的是java版本號(hào)是從45開始的,大版本發(fā)布,主版本號(hào)+1。高版本的jdk能向下兼容以前版本的class文件,但不兼容以后版本的class文件。各jdk編譯后的class文件版本號(hào)如下:常量池緊接著版本號(hào)后就是常量池入口。是第一個(gè)出現(xiàn)的表類型的數(shù)據(jù)項(xiàng)目。?由常量池容量計(jì)數(shù)值constant_pool_count及常量池constant_pool組成。?constant_pool_count占2個(gè)字節(jié)。如0×0016即十進(jìn)制的22,表示有
4、21項(xiàng)常量,從1開始到21。0有特殊含義,表示指向常量池的索引值數(shù)據(jù)不引用任何一個(gè)常量池項(xiàng)目。常量池主要存放字面量Literal和符號(hào)引用Symbolic References.字面量可能是文本字符串,或final的常量值.符號(hào)引用包括以下:·類或接口全限定名FullQualifiedName·字段名稱和描述符Descriptor·方法名稱和描述符常量池共有11種表結(jié)構(gòu)數(shù)據(jù).每個(gè)表均開始的第一位是u1類型的標(biāo)志位,表示哪種常量類型。但每個(gè)表的結(jié)構(gòu)都不相同。?如類或接口的符號(hào)引用為CONSTANTC
5、lassinfo。所有的常量池結(jié)構(gòu)嚴(yán)格以標(biāo)志位,表結(jié)構(gòu)其他數(shù)據(jù)類型 順序排列.各類型常量池表結(jié)構(gòu)如下表所示:實(shí)際中可以使用javap—verboseXXX.class輸出字節(jié)碼內(nèi)容。訪問標(biāo)志access_flagsu2類型,識(shí)別類或接口層次的訪問信息,如class是接口或類,是否public,是否abstract,是否final等。類索引、父類索引與接口索引集合類索引this_class及父類索引super_class均是u2類型,接口索引集合interfaces是一組u2類型的集合。確定類的繼承
6、關(guān)系.按照順序排列在訪問標(biāo)志之后。this_class,super_class指向CONSTANT_CLASS_info常量。通過該常量可以找到定義在CONSTANT_Utf8_info的全限定名字符串。字段表集合field_info緊接在interface后面的是fieldscount的計(jì)數(shù),它是類變量和實(shí)例變量的字段的數(shù)量總和。在這個(gè)計(jì)數(shù)后面的是不同長度的fieldinfo表的序列(fieldscount指出了序列中有多少個(gè)fieldinfo表)。描述接口或類中聲明的變量,包含類級(jí)變量或?qū)嵗?jí)
7、變量,不包含方法變量。信息包含:字段作用域、字段類型(類變量還是實(shí)例變量static)、可變性(final)、并發(fā)可見性(volatile)、可否序列化(transient)、字段數(shù)據(jù)類型、名稱等。?結(jié)構(gòu)如下表:字段修飾符放在accessflags項(xiàng)目中,它與類中的accessflags項(xiàng)目是非常相似的,都是一個(gè)u2的數(shù)據(jù)類型,其中可以設(shè)置的標(biāo)志位和含義如下表所示nameindex和descriptorindex都是對(duì)常量池的引用,分別代表著字段的簡單名稱及字段和方法的描述符.其中描述符的作用是用
8、來描述字段的數(shù)據(jù)類型、方法的參數(shù)列表(包括數(shù)量、類型以及順序)和返回值.根據(jù)描述符規(guī)則,基本數(shù)據(jù)類型(byte、char、double、float、int、long、short、boolean)及代表無返回值的void類型都用一個(gè)大寫字符來表示,而對(duì)象類型則用字符L加對(duì)象的全限定名來表示.對(duì)于數(shù)組類型,每一個(gè)維度將使用一個(gè)前置的”["字符來描述,如一個(gè)定義的”java。lang.String[][]“類型的二維數(shù)組,將被記錄為:”[[Ljava/lang/String;”,一個(gè)整型