本文以文章《Java文件編譯與反編譯(一):javac命令和javap命令》為基礎,進行深入分析
為了方便查看,此處將Test.class文件內容,進行如下調整:
cafebabe0000003400130a0004000f09000300100700110700120100016d010001490100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c65010003696e6301000328294901000a536f7572636546696c65010009546573742e6a6176610c000700080c00050006010004546573740100106a6176612f6c616e672f4f626a6563740021000300040000000100020005000600000002000100070008000100090000001d00010001000000052ab70001b100000001000a000000060001000000010001000b000c000100090000001f00020001000000072ab400020460ac00000001000a00000006000100000004000100 0d00 0000 0200 0e
Class類文件結構中的【表】:
cafebabe 指魔數
00 00 指次版本號
00 34指主版本號
0013對應十進制為:19,表示常量池中有19-1=18項常量
第1項常量: 0a對應十進制為:10代表 Methodref 0004對應十進制為:4指向常量池中聲明方法的類描述符的索引項:4 00 0f對應十進制為:15指向常量池中名稱及類型描述符的索引項:15第2項常量:09對應十進制為:9代表 Fieldref00 03對應十進制為:3指向常量池中聲明字段的類或接口的描述符的索引項:30010對應十進制為:16指向常量池中字段描述符的索引項:16第3項常量:07對應十進制為:7代表 Class0011對應十進制為:17指向全限定名常量項的索引:17第4項常量:07對應十進制為:7代表 Class0012對應十進制為:18指向全限定名常量項的索引:18第5項常量:01對應十進制為:1代表 UTF-80001對應十進制為:1UTF-8編碼的字符串占用的字節(jié)數為:1 個字節(jié)6d對應十進制為:109對應的ASCII值為:m第6項常量:01對應十進制為:1代表 UTF-80001對應十進制為:1UTF-8編碼的字符串占用的字節(jié)數為: 1個字節(jié)49對應十進制為:73對應的ASCII值為:I第7項常量:01對應十進制為:1代表 UTF-80006對應十進制為:6UTF-8編碼的字符串占用的字節(jié)數為:6 個字節(jié)3c 69 6e 69 74 3e對應的ASCII值為:<init>第8項常量:01對應十進制為:1代表 UTF-80003對應十進制為:3UTF-8編碼的字符串占用的字節(jié)數為: 3個字節(jié)28 29 56對應的ASCII值為:()V第9項常量:01對應十進制為:1代表 UTF-80004對應十進制為:4UTF-8編碼的字符串占用的字節(jié)數為:4 個字節(jié)43 6f 64 65對應的ASCII值為:Code第10項常量:01對應十進制為:1代表 UTF-8000f對應十進制為:15UTF-8編碼的字符串占用的字節(jié)數為: 15個字節(jié)4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65對應的ASCII值為:LineNumberTable第11項常量:01對應十進制為:1代表 UTF-80003對應十進制為:3UTF-8編碼的字符串占用的字節(jié)數為: 3個字節(jié)69 6e 63對應的ASCII值為:inc第12項常量:01對應十進制為:1代表 UTF-80003對應十進制為:3UTF-8編碼的字符串占用的字節(jié)數為: 3個字節(jié)28 29 49對應的ASCII值為:()I第13項常量:01對應十進制為:1代表 UTF-8000a對應十進制為:10UTF-8編碼的字符串占用的字節(jié)數為: 10個字節(jié)53 6f 75 72 6365 46 69 6c 65對應的ASCII值為:SourceFile第14項常量:01對應十進制為:1代表 UTF-80009對應十進制為:9UTF-8編碼的字符串占用的字節(jié)數為:9 個字節(jié)54 65 73 74 2e 6a 61 76 61對應的ASCII值為:Test.java
00 21指類或接口的訪問標志 代表ACC_PUBLIC(標志值0x0001)和ACC_SUPER(標志值0x0020)
00 03指常量池中類索引項為:3
00 04指常量池中父類索引項為:4
00 00指接口計數器值為:0
指 接口索引集合(若該類沒有實現任何接口,則接口計數器值為0,同時接口索引集合就不占用任何字節(jié))
00 01指字段計數器值為:1
指字段表集合
00 02指字段訪問標志此值表示:ACC_PRIVATE 字段是否為private
00 05指字段的簡單名稱指向常量池中的索引項:5
00 06指字段和方法的描述符指向常量池中的索引項:6
00 00指屬性表計數器值為:0
指屬性表集合
00 02指方法計數器值為;2
指字段表集合
00 01指方法訪問標志此值表示:ACC_PUBLIC 方法是否為public
00 07指方法名稱索引指向常量池中的索引項:7
00 08指方法描述符索引指向常量池中的索引項:8
00 01指屬性表計數器值為:1
指屬性表集合
00 01指屬性表集合大小為:1(表示該類有1個屬性)
指屬性表集合
屬性表的Code屬性:
attribute_name_index(u2)
00 09 指屬性名稱索引 指向常量池中的索引項:9
attribute_length(u4)
00 00 00 1d 對應十進制為:29指屬性值長度(注:屬性值的長度固定為整個屬性表長度減去6個字節(jié))
max_stack(u2)
00 01 指操作數棧深度的最大值為:1(注:在方法執(zhí)行的任意時刻,操作數棧都不會超過這個深度)
max_locals(u2)
00 01指局部變量表所需的存儲空間為:1(注:單位為Slot)
code_length(u4)
00 00 00 05代表字節(jié)碼長度為:5
code(u1)
2a b7 00 01 b1用于存儲字節(jié)碼指令的一系列字節(jié)流。 解析 2a b7 00 01 b1 的過程: 1. 讀入2a,查看虛擬機字節(jié)碼指令表得0x2a對應的指令為:aload_0,指將第0個Slot中的引用類型的 本地變量本地變量推送到操作數棧頂; 2. 讀入 b7 ,查看虛擬機字節(jié)碼指令表得0xb7對應的指令為:invokespecial,指以操作數棧頂的引用 類型的數據所指向的對象作為方法接收者,調用此對象的實力構造方法、私有方法或父類構造方法; 3.讀入 00 01,這是invokespecial的參數,指向常量池中的索引項:1; 4.讀入b1,查看虛擬機字節(jié)碼指令表得0xb1對應的指令為:return,指返回此方法,并且返回值為 void。(這條指令執(zhí)行后,當前方法結束)
exception_table_length(u2)
exception_table(exception_info)
attributes_count(u2)
attributes(attribute_info)