天天看點

一把小刀,直插 class 檔案的小心髒(4)

08、屬性表

屬性表是 class 檔案中的最後一部分,通常出現在字段和方法中。

來看這樣一段代碼。

public class AttributeTest {

   public static final int DEFAULT_SIZE = 128;

}

隻有一個常量 DEFAULT_SIZE,它屬于字段中的一種,就是加了 final 的靜态變量。先通過 jclasslib 看一下它當中一個很重要的屬性——ConstantValue,用來表示靜态變量的初始值。

一把小刀,直插 class 檔案的小心髒(4)

Attribute name index 指向常量池中值為“ConstantValue”的常量。

Attribute length 的值為固定的 2,因為索引隻占兩個位元組的大小。

Constant value index 指向常量池中具體的常量,如果常量類型為 int,指向的就是 CONSTANT_Integer_info。

我畫了一副圖,可以完整的表示字段的結構,包含屬性表在内。

一把小刀,直插 class 檔案的小心髒(4)
對應到 class 檔案中的位置如下圖所示。
一把小刀,直插 class 檔案的小心髒(4)
來看下面這段代碼。

public class MethodCode {
    public static void main(String[] args) {
        foo();
    }
    private static void foo() {
    }
}      

main 方法中調用了 foo 方法。通過 jclasslib 看一下它當中一個很重要的屬性——Code, 方法的關鍵資訊都存儲在裡面。

一把小刀,直插 class 檔案的小心髒(4)

Attribute name index 指向常量池中值為“Code”的常量。

Attribute length 為屬性值的長度大小。

bytecode 存儲真正的位元組碼指令。

exception table 表示方法内部的異常資訊。

maximum stack size 表示操作數棧的最大深度,方法執行的任意期間操作數棧深度都不會超過這個值。

maximum local variable 表示臨時變量表的大小,注意,并不等于方法中所有臨時變量的數量之和,當一個作用域結束,内部的臨時變量占用的位置就會被替換掉。

code length 表示位元組碼指令的長度。

對應 class 檔案中的位置如下圖所示。

一把小刀,直插 class 檔案的小心髒(4)

到此為止,class 檔案的内部算是剖析得差不多了,希望能對大家有所幫助。第一次拿刀,手有點顫,如果哪裡有不足的地方,歡迎大家在評論區毫不留情地指出來!