java图的建立field_《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的...
0.前言
了解JVM虛擬機原理是每一個Java程序員修煉的必經之路。但是由于JVM虛擬機中有很多的東西講述的比較寬泛,在當前接觸到的關于JVM虛擬機原理的教程或者博客中,絕大部分都是充斥的文字性的描述,很難給人以形象化的認知,看完之后感覺還是稀里糊涂的。
感于以上的種種,我打算把我在學習JVM虛擬機的過程中學到的東西,結合自己的理解,總結成《Java虛擬機原理圖解》 這個系列,以圖解的形式,將抽象的JVM虛擬機的知識具體化,希望能夠對想了解Java虛擬機原理的的Java程序員 提供點幫助。
讀完本文,你將會學到:
1、類中定義的field字段是如何在class文件中組織的
2、不同的數據類型在class文件中是如何表示的
3、static final類型的field字段的初始化賦值問題
1.概述
字段表集合是指由若干個字段表(field_info)組成的集合。對于在類中定義的若干個字段,經過JVM編譯成class文件后,會將相應的字段信息組織到一個叫做字段表集合的結構中,字段表集合是一個類數組結構,如下圖所示:
注意:這里所講的字段是指在類中定義的靜態或者非靜態的變量,而不是在類中的方法內定義的變量。請注意區別。
比如,如果某個類中定義了5個字段,那么,JVM在編譯此類的時候,會生成5個字段表(field_info)信息,然后將字段表集合中的字段計數器的值設置成5,將5個字段表信息依次放置到字段計數器的后面。
2. 字段表集合在class文件中的位置
字段表集合緊跟在class文件的接口索引集合結構的后面,如下圖所示:
3. Java中的一個Field字段應該包含那些信息?------字段表field_info結構體的定義
針對上述的字段表示,JVM虛擬機規范規定了field_info結構體來描述字段,其表示信息如下:
下面我將一一講解FIeld_info的組成元素:訪問標志(access_flags)、名稱索引(name_index)、描述索引(descriptor_index)、屬性表集合
4. field字段的訪問標志
如上圖所示定義的field_info結構體,field字段的訪問標志(access_flags)占有兩個字節,它能夠表述的信息如下所示:
舉例:如果我們在某個類中有定義field域:private static String str;,那么在訪問標志上,第15位ACC_PRIVATE和第13位ACC_STATIC標志位都應該為1。field域str的訪問標志信息應該是如下所示:
如上圖所示,str字段的訪問標志的值為0x000A,它由兩個修飾符ACC_PRIVATE和ACC_STATIC組成。
根據給定的訪問標志(access_flags),我們可以通過以下運算來得到這個域有哪些修飾符:
上面列舉的str字段的訪問標志的值為000A,那么分別域上述的標志符的特征值取&,結果為1的只有ACC_PRIVATE和ACC_STATIC,所以該字段的標志符只有有ACC_PRIVATE和ACC_STATIC。
5. 字段的數據類型表示和字段名稱表示
class文件對數據類型的表示如下圖所示:
field字段名稱,我們定義了一個形如private static String str的field字段,其中"str"就是這個字段的名稱。
class文件將字段名稱和field字段的數據類型表示作為字符串存儲在常量池中。在field_info結構體中,緊接著訪問標志的,就是字段名稱索引和字段描述符索引,它們分別占有兩個字節,其內部存儲的是指向了常量池中的某個常量池項的索引,對應的常量池項中存儲的字符串,分別表示該字段的名稱和字段描述符。
6.屬性表集合-----靜態field字段的初始化
在定義field字段的過程中,我們有時候會很自然地對field字段直接賦值,如下所示:
publicstaticfinalintMAX=100;
publicintcount=0;
對于虛擬機而言,上述的兩個field字段賦值的時機是不同的:
對于非靜態(即無static修飾)的field字段的賦值將會出現在實例構造方法()中
對于靜態的field字段,有兩個選擇:1、在靜態構造方法()中進行;2 、使用ConstantValue屬性進行賦值
Sun javac編譯器對于靜態field字段的初始化賦值策略
目前的Sun javac編譯器的選擇是:如果使用final和static同時修飾一個field字段,并且這個字段是基本類型或者String類型的,那么編譯器在編譯這個字段的時候,會在對應的field_info結構體中增加一個ConstantValue類型的結構體,在賦值的時候使用這個ConstantValue進行賦值;如果該field字段并沒有被final修飾,或者不是基本類型或者String類型,那么將在類構造方法()中賦值。
對于上述的public static final init MAX=100;? javac編譯器在編譯此field字段構建field_info結構體時,除了訪問標志、名稱索引、描述符索引外,會增加一個ConstantValue類型的屬性表。
7.實例解析:
定義如下一個簡單的Simple類,然后通過查看Simple.class文件內容并結合javap -v Simple?生成的常量池內容,分析str field字段的結構:
packagecom.louis.jvm;
publicclassSimple?{
privatetransientstaticfinalString?str?="This?is?a?test";
}
注:
1.?字段計數器中的值為0x0001,表示這個類就定義了一個field字段
2.?字段的訪問標志是0x009A,二進制是00000000 10011010,即第9、12、13、15位標志位為1,這個字段的標志符有:ACC_TRANSIENT、ACC_FINAL、ACC_STATIC、ACC_PRIVATE;
3.名稱索引中的值為0x0005,指向了常量池中的第5項,為“str”,表明這個field字段的名稱是str;
4.?描述索引中的值為0x0006,指向了常量池中的第6項,為"Ljava/lang/String;",表明這個field字段的數據類型是java.lang.String類型;
5.屬性表計數器中的值為0x0001,表明field_info還有一個屬性表;
6.屬性表名稱索引中的值為0x0007,指向常量池中的第7項,為“ConstantValue”,表明這個屬性表的名稱是ConstantValue,即屬性表的類型是ConstantValue類型的;
7.屬性長度中的值為0x0002,因為此屬性表是ConstantValue類型,它的值固定為2;
8.常量值索引 中的值為0x0008,指向了常量池中的第8項,為CONSTANT_String_info類型的項,表示“This is a test” 的常量。在對此field賦值時,會使用此常量對field賦值。
8.您還需要了解什么
簡單地說,對于一個類而言,它有兩部分組成:field字段和?method方法。本文主要介紹了field字段,那還剩些一個method方法method方法啦。method方法可是說是class文件中最為重要的一部分了,它包含了方法的實現代碼,即機器指令,機器指令是整個class文件的核心,如果你想了解method方法和其內的機器指令 是如何在class文件中組織的,請看下文:
總結
以上是生活随笔為你收集整理的java图的建立field_《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: r语言折线图_R语言做多变量可视化分析?
- 下一篇: 在python中字典和集合都是用一对什么