先看一下java字节码的结构:
图1:
图2:
图3:
- Class字节码中有2中数据结构
- 字节数据直接量:这是基本的数据类型。共细分为u1、u2、u4、u8四种,分别代表连续的1个字节
、2个字节、四个字节、8个字节组成的整体数据。 表(数组):表示由多个基本数据或其他表,按照既定顺序组成的大的数据集合。表是有结构的,
它的结构体现在:组成表的成分所在的位置和顺序都是已经严格定义好的。
图4:
上面的表中描述了11种数据类型的结构,其实在jdk1.7之后又增加了3种(CONSTANT_Method_info\CONSTANT_Method_Type\CONSTANT_InvokeDynamic_info).
这样一共是14种。
Access_Flag访问标志
访问标志信息包括该Class文件是类还是接口,是否被定义成public,是否是abstract,如果是类
是否被声明成final,通过上面的源代码(MyTest1),我们知道该文件是类并且是public。
图5:
那接下来看一下access_flag:
图6:
从00 21 开始就是访问修饰符:00 21 我们去图5里边找不到,那是因为00 21是由0x0001|0x0020=0x0021得到的,即,java不会穷举所有的访问修饰组合,而是用并集的方式得到的。当前表示我们的MyTest1是一个acc_public和acc_super。
然后是this Class Name,也是占据2个字节:00 03(十进制3) :对应的是常量池里边的3号常量:
【#3 = Class #22 // com/twodragonlake/jvm/bytecode/MyTest1】
接下来是父类的名字,占2个字节,00 04 (十进制4),指向的是常量池的4号常量:【#4 = Class #23 // java/lang/Object】
接口:当前MyTest1没有实现人很接口,所以说接口的数量是0,即:00 00 所以接口表就不会再出现了。
成员变量:由成员变量数量加成员变量表组成。成员变量数量:00 01 (十进制,即一个成员变量),然后是成员变量表:00 02 (十进制2,即常量池的2号常量):
【#2 = Fieldref #3.#21 // com/twodragonlake/jvm/bytecode/MyTest1.a:I】
字段表集合重点内容
字段表用于描述类和接口中声明的变量。
这里的字段包含了类级别变量以及实例变量,但是不包括方法内部声明的局部变量。
类型 | 名称 | 数量 |
---|---|---|
u2 | access_flags | 1 |
u2 | name_index | 1 |
u2 | descriptor_index | 1 |
u2 | attributes_count | 1 |
u2 | attributes | 1 |
图7:
所以接下里的00 01 表示的就是属性表的数量,此处表示由有一个字段,然后数量之后是访问标示: 00 02 ,00 02 在图5里边没有列出,表示的是私有的private。
紧接着是名字的索引和描述符的索引: 00 05 00 06 分别指向的是常量池的:
[#5 = Utf8 a]
[#6 = Utf8 I ]
然后是attributes_count : 00 00 是0个,所以attributes表就不会出现。
ok,字段信息,到此梭哈完毕,下一章搞一下方法表。