方法表集合 前面的魔數,次版本號,主板本號,常量池入口,常量池,訪問標誌,類索引,父類索引,介面索引集合,欄位表集合,那麼再接下來就是方法表了. 方法表集合 前面的魔數,次版本號,主板本號,常量池入口,常量池,訪問標誌,類索引,父類索引,介面索引集合,欄位表集合,那麼再接下來就是方法表了. 方法表的 ...
方法表集合
前面的魔數,次版本號,主板本號,常量池入口,常量池,訪問標誌,類索引,父類索引,介面索引集合,欄位表集合,那麼再接下來就是方法表了.
方法表的構造如同欄位表一樣,依次包括了訪問標誌(access_flags),名稱索引(name_index),描述符索引(descriptor_index),屬性表集合(attributes)幾項.
方法表結構:
類型 | 名稱 | 數量 |
u2 | access_flags | 1 |
u2 | name_index | 1 |
u2 | descriptor_index | 1 |
u2 | attributes_count | 1 |
attribute_info | attributes | attributes_count |
方法訪問標誌:
標誌名稱 | 標誌值 | 含義 |
ACC_PUBLIC | 0x00 01 | 方法是否為public |
ACC_PRIVATE | 0x00 02 | 方法是否為private |
ACC_PROTECTED | 0x00 04 | 方法是否為protected |
ACC_STATIC | 0x00 08 | 方法是否為static |
ACC_FINAL | 0x00 10 | 方法是否為final |
ACC_SYHCHRONRIZED | 0x00 20 | 方法是否為synchronized |
ACC_BRIDGE | 0x00 40 | 方法是否是有編譯器產生的方法 |
ACC_VARARGS | 0x00 80 | 方法是否接受參數 |
ACC_NATIVE | 0x01 00 | 方法是否為native |
ACC_ABSTRACT | 0x04 00 | 方法是否為abstract |
ACC_STRICTFP | 0x08 00 | 方法是否為strictfp |
ACC_SYNTHETIC | 0x10 00 | 方法是否是有編譯器自動產生的 |
方法里的Java代碼,經過編譯器編譯成位元組碼指令後,存放在方法屬性表集合中一個名為"Code"的屬性裡面,屬性表作為calss文件格式中最具擴展的一種數據項目.
在Java語言中,要重載一個方法,除了要與原方法具有相同的簡單名稱之外,還要求必須擁有一個與原方法不同的簽名,特征簽名就是一個方法中各個參數在常量池中的欄位符號引用的集合,也就是因為返回值不會包含在特征簽名中,因此Java語言裡面是無法僅僅靠返回值的不同來堆一個已有方法進行重載的.但是在class文件格式中,特征簽名的範圍更大一些,只要描述符不是完全一致的兩個方法也可以共存.也就是說,如果兩個方法有相同的名稱和特征簽名,但是返回值不同,那麼也是可以合法共存與同一個class文件中的.
下麵繼續前面分析的class文件
源文件:
javap分析的常量池:
class文件分析:
直接看方法表部分(有點亂),首先是右下角的methods_count:0x00 02表示方法集中有兩個方法.access_flags:0x00 01表示訪問標誌值為1,對應上面的方法訪問標誌表的public,在看源文件的方法確實是public.name_index:0x00 07表示方法的名稱索引為7,對應上面的常量池7,為"<init>".decriptor_index:0x00 08代表描述符索引值為8,對應上面常量池的"()v".attributes_count:0x00 01代表此方法的屬性表集合有一項屬性,屬性的名稱索引為0x00 09,對應上面常量池9為"code ",說明此屬性是方法的位元組碼描述.