Class文件解讀(四)

接上篇:http://www.javashuo.com/article/p-oibmohyh-mb.htmljava

字段表集合數組

        字段表(field_info)用於描述接口或者類中聲明的變量。字段(field)包括類級變量以及實例級變量,但不包括在方法內部聲明的局部變量。在java中描述一個字段能夠包含的信息有:字段的做用域(public、private、protected修飾符)、是實例變量仍是類變量(static修飾符)、可變性(final)、併發可見性(volatile修飾符,是否強制從主內存讀寫)、能否被序列化(transient修飾符)、字段數據類型(基本類型、對象、數組)、字段名稱。上述這些信息中,各個修飾符都是布爾值,要麼有某個修飾符,要麼沒有,很適合使用標誌位來表示。而字段叫什麼名字、字段被定義爲何數據類型,這些都是沒法固定的,只能引用常量池中的常量來描述。下表描述的字段表結構。併發

              

       字段修飾符放在access_flags項目中,它與類中的access_flags是很是相似的,都是一個u2的數據類型,其中能夠設置的表示位和含義以下表。spa

                

跟隨access_flags標誌的是兩項索引值:name_index和descriptor_index。它們都是對常量池的引用,分別表明着字段的簡單名稱及字段和方法的描述符。如今須要解釋一下「簡單名稱」、「描述符」以及前面出現過屢次的「全限定名」這三種特殊字符串的概念。.net

       全限定名很好理解,其實就是把類全名中的"."換成"/"而已,爲了使鏈接的多個全限定名之間不產生混淆,在使用時最後通常會加一個";"表示全限定名結束。簡單名稱是指沒有類型和參數修飾的方法或者字段名稱。對象

        相對於全限定名和簡單名稱來講,方法和字段的描述符就要複雜一些。描述符的做用是用來描述字段的數據類型、方法的參數列表(包括數量、類型以及順序)和返回值。根據描述符規則,基本數據類型(byte、char、double、float、int、long、short、boolean)以及表明無返回值的void類型都用一個大寫字符來表示,而對象類型則用字符L加對象的全限定名來表示。blog

                                                                    描述符標識字符含義繼承

標識字符 含義 標識字符 含義
B 基本類型byte J 基本類型long
C 基本類型char S 基本類型short
D 基本類型double Z 基本類型boolean
F 基本類型float V 特殊類型void
I 基本類型int L 對象類型,如Ljava/lang/Object

對於數組類型,每一維度將使用一個前置的"["字符來描述,如一個定義爲"java.lang.String[][]"類型的二維數組,將被記錄爲:"Ljava/lang/String;",一個整型數組"int[]"將被記錄爲"[I"。索引

        用描述符來描述方法時,按照先參數列表,後返回值的順序描述,參數列表按照參數的嚴格順序放在一組小括號"()"以內。如方法void inc()的描述符爲"()V",將方法java.lang.String toString()的描述符爲"()Ljava/java/String;",方法int indexOf(char[] source,int sourceCount,char[] target,int targetOffset,int targetCount,int fromIndex)的描述符爲「([CII[CII])I」。接口

        字段表都包含的固定數據項目到descriptor_index爲止就結束了,不過在descriptor_index以後跟隨着一個屬性表集合用於存儲一些額外的信息,字段均可以在屬性表中描述零至多項的額外信息。對於本例中的字段n,它的屬性表計數器爲0,也就是沒有須要額外描述的信息,可是對於本例中的m字段,它的屬性表爲1,結合https://my.oschina.net/u/3345762/blog/880152中常量池信息及下圖能夠看出,它存在一項名稱爲ConstantValue的屬性,其值指向常量5(關於ConstantValue型屬性結構會在下面篇章中闡述到,此處偏移地址Ox00000120,值爲Ox0008,表示指向常量池第八個常量,查詢得其值爲ConstantValue,偏移地址Ox00000130,值爲Ox0009,表示指向常量池中第九個常量,查詢得其值爲5)。

                        

       字段表集合中不會列出從超類或者父接口中繼承而來的字段,但有可能列出本來Java代碼之中不存在的字段,譬如在內部類中爲了保持對外部類的訪問性,會自動添加指向外部類實例的字段,另外,在Java語言中字段是沒法重載的,兩個字段的數據類型、修飾符無論是否相同,都必須使用不同的名稱,可是對於字節碼來說,若是兩個字段的描述符不一致,那字段重名就是合法的。

下篇:http://www.javashuo.com/article/p-xdetuxcw-ky.html

相關文章
相關標籤/搜索