天天看點

Class檔案結構介紹[常量池]

概述

 常量池是緊接着主次版本号之後出現的,常量池可以了解為class檔案之中的資源倉庫,它是Class檔案結構中與其他項目管理最多的資料類型,也是占用Class檔案空間最大的資料項目之一,同時它還是在Class檔案中第一個出現的表類型資料項目。案例代碼還是和前一篇的一樣,如下:

public class Test {

    private int a;
    
    public int  run(){
        System.out.println("波波烤鴨");
        return a=1;
    }
}      

常量池介紹

1.結構

 由于常量池中常量的數量是不固定的,是以常量池的入口需要放置一項u2類型的資料表示常量池容量計數值,如下:

Class檔案結構介紹[常量池]

 本例中常量池中的常量的個數是35個,注意此處和java中的習慣不一樣,這個容器的計數是從1而不是從0開始的,上圖的結果是36,代表常量池中有35項常量,索引範圍為1~35,0項常量有特殊考慮,當表達“不引用任何一個常量池項目”的含義時可以把索引值置為0來标示。

Class檔案結構介紹[常量池]
Class檔案結構介紹[常量池]

 在constant_pool_count後是一個表資料類型constant_pool其中存儲的就是constant_pool_count計數的那35個常量項。

2.存儲資料的類型

 常量池中主要存放兩大類型常量:字面量(Literal)和符号引用(Symbolic References).

Class檔案結構介紹[常量池]

注意:

   全限定名中的".“被替換為”/".比如

Class檔案結構介紹[常量池]

   常量池中存儲着最基本的資訊,不僅程式會用到,而且Class檔案本身也會通過#來引用

Class檔案結構介紹[常量池]

符号引用:

 符号引用以一組符号來描述所引用的目标(com/dpb/test/Test),符号可以是任何形式的字面量,隻要使用時能無歧義的定位到目标即可,符号引用和虛拟機實作的記憶體布局無關,引用的目标并不一定已經加載到了記憶體中。

Class檔案結構介紹[常量池]

直接引用

 直接引用可以指向目标的指針、相對偏移量或者是一個能夠直接定位到目标的句柄。直接引用于虛拟機的記憶體布局相關,同一個符号引用在不同的虛拟機執行個體上翻譯出來的直接引用一般不同。如果有了直接引用,那麼,所引用的目标一定已經在記憶體中存在。

3.表的存儲結構說明

 通過觀察我們發現,在這14中表中都有些相同的特定,比如表的開始的第一位都是一個u1類型的标志位(tag),代表目前屬于哪種類型,具體的标志說明如下:

Class檔案結構介紹[常量池]

參考此表我們就能夠看出這35個常量項的類型了。

Class檔案結構介紹[常量池]

 從上面的結構我們也發現不同類型的表資料結構也是不相同的,詳細結構如下,參考後會更加詳細些。

Class檔案結構介紹[常量池]
Class檔案結構介紹[常量池]
Class檔案結構介紹[常量池]

參考《深入了解Java虛拟機》