Java文件编译与反编译(二):class文件解析
本文以文章《Java文件编译与反编译(一):javac命令和javap命令》为基础,进行深入分析
为了方便查看,此处将Test.class文件内容,进行如下调整:
cafebabe0000003400130a0004000f09000300100700110700120100016d010001490100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c65010003696e6301000328294901000a536f7572636546696c65010009546573742e6a6176610c000700080c00050006010004546573740100106a6176612f6c616e672f4f626a6563740021000300040000000100020005000600000002000100070008000100090000001d00010001000000052ab70001b100000001000a000000060001000000010001000b000c000100090000001f00020001000000072ab400020460ac00000001000a00000006000100000004000100 0d00 0000 0200 0e
Class类文件结构中的【表】:
注:本文解析将会按照该表顺序进行。
magic
cafebabe 指魔数
minor_version
00 00 指次版本号
major_version
00 34指主版本号
constant_pool_count
0013对应十进制为:19,表示常量池中有19-1=18项常量
constant_pool
第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编码的字符串占用的字节数为:1 个字节6d对应十进制为:109对应的ASCII值为:m第6项常量:01对应十进制为:1代表 UTF-80001对应十进制为:1UTF-8编码的字符串占用的字节数为: 1个字节49对应十进制为:73对应的ASCII值为:I第7项常量:01对应十进制为:1代表 UTF-80006对应十进制为:6UTF-8编码的字符串占用的字节数为:6 个字节3c 69 6e 69 74 3e对应的ASCII值为:<init>第8项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节28 29 56对应的ASCII值为:()V第9项常量:01对应十进制为:1代表 UTF-80004对应十进制为:4UTF-8编码的字符串占用的字节数为:4 个字节43 6f 64 65对应的ASCII值为:Code第10项常量:01对应十进制为:1代表 UTF-8000f对应十进制为:15UTF-8编码的字符串占用的字节数为: 15个字节4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65对应的ASCII值为:LineNumberTable第11项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节69 6e 63对应的ASCII值为:inc第12项常量:01对应十进制为:1代表 UTF-80003对应十进制为:3UTF-8编码的字符串占用的字节数为: 3个字节28 29 49对应的ASCII值为:()I第13项常量:01对应十进制为:1代表 UTF-8000a对应十进制为:10UTF-8编码的字符串占用的字节数为: 10个字节53 6f 75 72 6365 46 69 6c 65对应的ASCII值为:SourceFile第14项常量:01对应十进制为:1代表 UTF-80009对应十进制为:9UTF-8编码的字符串占用的字节数为:9 个字节54 65 73 74 2e 6a 61 76 61对应的ASCII值为:Test.java
access_flag类或接口的访问标志
00 21指类或接口的访问标志 代表ACC_PUBLIC(标志值0x0001)和ACC_SUPER(标志值0x0020)
this_class
00 03指常量池中类索引项为:3
super_class
00 04指常量池中父类索引项为:4
interfaces_count
00 00指接口计数器值为:0
interfaces
指 接口索引集合(若该类没有实现任何接口,则接口计数器值为0,同时接口索引集合就不占用任何字节)
fields_count
00 01指字段计数器值为:1
fields
指字段表集合
access_flags(u2)
00 02指字段访问标志此值表示:ACC_PRIVATE 字段是否为private
name_index(u2)
00 05指字段的简单名称指向常量池中的索引项:5
descriptor_index(u2)
00 06指字段和方法的描述符指向常量池中的索引项:6
attributes_count(u2)
00 00指属性表计数器值为:0
attributes
指属性表集合
methods_count
00 02指方法计数器值为;2
methods
指字段表集合
access_flags(u2)
00 01指方法访问标志此值表示:ACC_PUBLIC 方法是否为public
name_index(u2)
00 07指方法名称索引指向常量池中的索引项:7
descriptor_index(u2)
00 08指方法描述符索引指向常量池中的索引项:8
attributes_count(u2)
00 01指属性表计数器值为:1
attributes
指属性表集合
attributes_count
00 01指属性表集合大小为:1(表示该类有1个属性)
attributes
指属性表集合
属性表的Code属性:
attribute_name_index(u2)
00 09 指属性名称索引 指向常量池中的索引项:9
attribute_length(u4)
00 00 00 1d 对应十进制为:29指属性值长度(注:属性值的长度固定为整个属性表长度减去6个字节)
max_stack(u2)
00 01 指操作数栈深度的最大值为:1(注:在方法执行的任意时刻,操作数栈都不会超过这个深度)
max_locals(u2)
00 01指局部变量表所需的存储空间为:1(注:单位为Slot)
code_length(u4)
00 00 00 05代表字节码长度为:5
code(u1)
2a b7 00 01 b1用于存储字节码指令的一系列字节流。 解析 2a b7 00 01 b1 的过程: 1. 读入2a,查看虚拟机字节码指令表得0x2a对应的指令为:aload_0,指将第0个Slot中的引用类型的 本地变量本地变量推送到操作数栈顶; 2. 读入 b7 ,查看虚拟机字节码指令表得0xb7对应的指令为:invokespecial,指以操作数栈顶的引用 类型的数据所指向的对象作为方法接收者,调用此对象的实力构造方法、私有方法或父类构造方法; 3.读入 00 01,这是invokespecial的参数,指向常量池中的索引项:1; 4.读入b1,查看虚拟机字节码指令表得0xb1对应的指令为:return,指返回此方法,并且返回值为 void。(这条指令执行后,当前方法结束)
exception_table_length(u2)
exception_table(exception_info)
attributes_count(u2)
attributes(attribute_info)
注:ASCII码值对照表
赞 (0)