1. 程式人生 > >jvm學習筆記(三)類檔案結構、java方法數65535上限的原因

jvm學習筆記(三)類檔案結構、java方法數65535上限的原因

瞭解class類檔案結構,對於學習smali也是有必要的!

一、class類檔案的結構(8位位元組,一個位元組佔8位,以位元組為基礎單位的二進位制流)
儲存結構:class檔案是一組以位元組(8位)為基礎單位的二進位制流,各資料嚴格按照順序緊湊排列在class檔案中,中間沒有任何分隔符。需要佔用一個位元組(8位)以上空間的資料,會按照高位在前的方式分割成若干個位元組(8位)進行儲存。
概念:無符號數和表組成。無符號數是基本資料型別,用來描述數字、索引引用、數量值、或者按照UTF-8編碼構成字串值。表是由多個無符號數或其他表作為資料項構成的符合資料型別,用來描述有層次關係的符合結構資料。
無符號型別為基本型別,以u1、u2、u4、u8表示1個位元組、2個位元組、4個位元組、8個位元組的無符號數。
1、魔數與Class檔案的版本
1)class檔案的頭4個位元組為魔數,唯一作用,確定該檔案是否為一個能被虛擬機器接受的class檔案。【class檔案型別的標識】
2)class檔案的魔數值為:0xCAFEBABE
3)魔數後面的4個位元組為class檔案的版本號,第5、6個位元組是次版本號(Minor Version),第7、8個位元組為主機板本號(Major Version)
2、常量池(class檔案結構中與其他專案關聯最多的型別、佔用class檔案空間最大的資料之一、class中第一個出現的表)
1)常量池入口,有一個u2型別資料表示常量池容量,常量池容量計數是從1開始的


 0用來表示某些指向常量池的索引表達不引用任何一個常量池專案,把索引值設定為0
2)常量池存放兩大類常量:字面量、符號引用。
 字面量:文字字串、宣告為final的常量值
 符號引用:屬於編譯原理的概念
    a:類和介面的全限定名   b:欄位的名稱和描述符   c:方法的名稱和描述符
虛擬機器執行時,需要從常量池獲取對應的符號引用,再在類建立時或執行時解析、翻譯到具體記憶體地址中。

3)常量池的專案型別中有一項為 CONSTANT_Utf8_info表示UTF-8編碼的字串;

                    CONSTANT_Utf8_info的結構如下:
                       型別        名稱數量
                        u1          tag          1
                        u2          length          1
                        u1  bytes         length

 class檔案中方法、欄位等都需要引用CONSTANT_Utf8_info型常量來描述名稱,所以CONSTANT_Utf8_info型常量的最大長度即u2型別能表達的最大值,也是Java中方法、欄位名的最大長度。
u2型別,表示2個位元組,16位,能表示的最大值為 2的16次方,也就是65536,而常量池容量計數是從1開始的,所以u2型別最多能表示65535個不同的值
所以Java程式中如果定義了超過64KB英文字元的變數或方法名,將無法編譯。

3、訪問標誌
常量池後面兩個位元組表示訪問標誌,用於識別一些類、介面層次的訪問資訊。
包括:class是類還是介面、是否定義為public型別、是否為abstract型別、如果是類的話是否宣告為final。
4、類索引、父類索引與介面索引集合
1)類索引、父類索引與介面索引集合都按順序排列在訪問標誌之後
2)類索引、父類索引都是u2型別(2個位元組型別)的資料,介面索引集合是一組u2型別的資料集合。
3)類索引用於確定類的全限定名
4)父類索引用於確定類的父類的全限定名
5)class檔案中由這三項資料來確定這個類的繼承關係。

5、欄位表集合
1)欄位表:用於描述介面/類中宣告的變數。欄位包括類級變數、例項級變數,不包括方法內部宣告的區域性變數。
6、方法表集合

7、屬性表集合