JVM學習筆記(二)

上次我們分析了常量池,根據class文件格式,我們看到常量池後面是access flag訪問標誌,用於表示這個class文件代表的類的訪問相關信息,比如是public還是private,是final或者abstract,還有最重要的,是類還是接口等等。具體見下圖(圖片來源網絡)

在這裏插入圖片描述

訪問標誌是個U2類型,在我們的例子中,這裏的值爲0x0021,根據上圖,正好是0x0001 & 0x0020的結果,所以該標誌位表示的就是ACC_PUBLICACC_SUPERACC_PUBLIC即public,ACC_SUPER如上圖的解釋,在jdk1.2之後編譯出來的類該標誌都爲真,目前我們先不用深究。

接下來是一個U2的this_class,表示當前類,它指向一個CONSTANT_CLASS_INFO,在例子中該數值爲0x0005,從上篇文章的分析中我們可以看到該值爲“First”。如下圖

在這裏插入圖片描述

在這裏插入圖片描述

同理,對於下一個super_class也一樣,它表示父類,在本例中它的值是0x0006,根據上篇分析,它對應的值是java/lang/Object。除了Object類所有的類都有父類,所以只有Object類的super_class的值爲0,其他類都不爲0。

接下來是interfaces_count表示有多少接口。在本列中沒有實現接口,所以這值爲0x0000,也就是說後面沒有interfaces這個屬性。

接下來是fields_count,表示字段表集合。這裏fields_count的值爲0x0000表示沒有fields

接下來是method_count,表示方法表集合,它的值爲0x0002,表示有兩個方法methodsmethods的格式如下圖(圖片來源

在這裏插入圖片描述

首先是一個U2的access_flags,它的內容和前面說的常量池後面的access_flags差不多,它代表的內容如下圖(圖片來源

在這裏插入圖片描述

我們例子中的值爲0x0001,即爲public。

接下來是name_index 0x0007,指向常量池第七個參數,即。
descriptor_index 0x0008,指向常量池第八個參數,即()V。這兩個參數表示我們例子中的First類的構造方法,例子中沒有寫構造方法,所以First會使用默認的java/lang/Object的構造方法,沒有參數,返回void。

接下來是attributes_count 0x0001,表示有一個屬性表,屬性表通常的結構如下圖(來源地址

在這裏插入圖片描述

屬性表第一個是屬性表的名稱attribute_name_index,在例子中的值爲0x0009,指向常量池中的#9,即Code(每一個屬性表的名稱都會指向常量池)。

java方法體中的代碼都存儲在Code屬性表中

Code屬性表的結構如下圖(圖片來源與上圖一樣)
在這裏插入圖片描述

attribute_length U4 001d 29 屬性表長度
max_stack U2 0001 1 操作數棧最大深度
max_locals U2 0001 1 局部變量表所需存儲空間
code_length U4 0000 0005 5 字節碼長度
code U1 字節碼 值如下
2a aload_0
b7 invokespecial
0001 invokespecial的參數 #1 java/lang/Object.;<>V
b1 return
這裏表示執行了對象的初始化工作,具體字節碼的執行部分我們後面再分析。
exception_table_length U2 0000 0 異常長度
由於長度爲0所以這裏沒有exception_table
接下來又是一個屬性表,大家可以試着自己分析,這個屬性表爲LineNumberTable,用於描述字節碼和源碼之間的關係,也就是程序報錯後可以讓我們看到到底是哪行報的錯。結構如下圖(來源同上)
在這裏插入圖片描述

line_number_info的結構如下

start_pc u2
line_number u2

到此方法表分析完畢,對比文件格式表,我們看到方法表之後又是一個attirbutes_count,那我們重複上述工作繼續。
attributes_count的值爲0001,表示有一個屬性表
attribute_name_index的值爲000d即13,指向常量池的第十三個值,即SourceFile。SourceFile用於記錄生成這個class文件的源碼文件名稱,它的結構如下

attribute_name_index u2
attribute_length u4
sourcefile_index u2

按照格式分析如下
attribute_length 0000 0002,表示該屬性有兩個字節,即000e。
sourcefile_index 000e 即14,指向常量池第十四個值,即First.java

至此整個helloworld就分析完了,有不對的地方歡迎大家指正
.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章