Class文件结构分析
1. Class文件的结构概览图
2. 每一项数据说明
类型 |
名称 |
数量 |
说明 |
u4 |
magic |
1 |
魔数:确定一个文件是否是Class文件 |
u2 |
minor_version |
1 |
Class文件的次版本号 |
u2 |
major_version |
1 |
Class文件的主版本号:一个JVM实例只能支持特定范围内版本号的Class文件(可以向下兼容)。 |
u2 |
constant_pool_count |
1 |
常量表数量 |
cp_info |
constant_pool |
constant_pool_count-1 |
常量池:以理解为Class文件的资源仓库,后面的其他数据项可以引用常量池内容。 |
u2 |
access_flags |
1 |
类的访问标志信息:用于表示这个类或者接口的访问权限及基础属性。 |
u2 |
this_class |
1 |
指向当前类的常量索引:用来确定这个类的的全限定名。 |
u2 |
super_class |
1 |
指向父类的常量的索引:用来确定这个类的父类的全限定名。 |
u2 |
interfaces_count |
1 |
接口的数量 |
u2 |
interfaces |
interfaces_count |
指向接口的常量索引:用来描述这个类实现了哪些接口。 |
u2 |
fields_count |
1 |
字段表数量 |
field_info |
fields |
fields_count |
字段表集合:描述当前类或接口声明的所有字段。 |
u2 |
methods_count |
1 |
方法表数量 |
method_info |
methods |
methods_count |
方法表集合:只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。 |
u2 |
attributes_count |
1 |
属性表数量 |
attributes_info |
attributes |
attributes_count |
属性表集合:用于描述某些场景专有的信息,如字节码的指令信息等等。 |
3. Class文件16进制解析
3.1 魔数。
- Class文件开始是4个字节定义为魔数(Magic Number);
- 唯一作用:确定一个文件是否是Class文件;
- 魔数可以自由选择,只要没有广泛使用而且不会引起混淆的即可,这样就不会因为扩展名改变而无法识别;其他许多文件类型格式头都存在魔数,如gif、jpeg等
- Class文件的魔数为"0xCAFEBABE"(咖啡宝贝),比照ClassFileTest.class如下:
3.2 方法表解析
00 01 访问控制符 public
00 11 这里11是16进制转10进制为17,对应 Constant pool: #17 = Utf8 bar
00 0b 描述符0b是16进制转10进制为11,对应 Constant pool: #11 = Utf8 ()V
翻译过来:public void bar()
00 01 表示有1个属性表attribute_count
属性表attribute_info(u2,u4,u1*length)
00 0c 表示attribute_name_index,索引,这里0c是16进制转10进制为12,对应 Constant pool: #12 = Utf8 Code
00 00 00 38 表示attribute_length,代码占的大小,这里38是16进制转10进制为56,表示bar()方法占了56个字节
00 02 表示max_stack最大栈深是2
00 01 表示max_locals最大变量数是1
00 00 00 0a 表示code_length代码行数,这里0a是16进制转10进制为10
args_size 方法的参数有多少个(默认是this,如果方法是static那么就是0)
对应字节码
00 02 00 01 00 00 00 0a b2 00 02 b2 00 03 b6
00 04 b1 00 00 00 02 00 0d 00 00 00 0a 00 02 00
00 00 0f 00 09 00 10 00 0e 00 00 00 0c 00 01 00
00 00 0a 00 0f 00 10 00 00
b2 getstatic
00 nop
03 iconst_0
b6 invokevirtual
04 iconst_1
本地行号表
LineNumberTable:
line 15: 0
line 16: 9
本地变量表
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this Lcom/cecjx/TestM;
Start+Length 表示一个本地变量的作用域(0对应行是15,10对应行是17||即表示在该方法中,该变量的作用范围是15行到17行)
Slot 表示几个槽存储
Name 表示简单名字
签名
Signature
伪泛型。
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: iconst_2
1: putstatic #3 // Field m:I
4: return
LineNumberTable:
line 12: 0