Class文件格式
u1代表1个字节,class文件是一组以8位字节为基础单位的二进制流。
类型 | 名称 | 数量 |
u4 | magic | 1 |
u2 | minor_version | 1 |
u2 | major_version | 1 |
u2 | constant_pool_count | 1 |
cp_info | constant_pool | constant_pool_count - 1 |
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 | attribute_count | 1 |
attribute_info | attributes | attributes_count |
1、魔数
java class文件结构(此处用winhex打开class文件)
其中0xCAFEBABE,即class文件的魔数,用来确认这个文件是否是能被jvm接受的class文件。
2、版本
按照class文件格式的顺序,接下来是版本号
52代表我的JDK版本是1.8(1.7是51 or 50 or 48)
3、常量池
1、参考第一张图class文件格式,可以看到cp_info常量池的数量是constant_pool_count-1,计数值减1(因为
常量池容量计数值是从1开始)。这就表示常量池中有28项常量。
2、打开cmd,javap -verbose App打印出常量表
其中以第七项常量为例
结合常量池14种常量项结构总表
0x01表示指向第一种常量项CONSTANT_Utf8_info:tag u1,length u2,bytes u1长度为length长度,
即0x0006为length值,也就是字符串长度,接下来0x3C696E69743E,即为bytes包含的内容,每个字符长u1;
也就是图中的"<init>"
4、访问标志
在常量池结束后的两个字节代表访问标志
因为我的App.java中只涉及到public0x0001和super0x0020,所以该处值为0x0001|0x0020=0x0021(位或运算)
5、索引
类索引、父类索引、接口索引集合都是u2类型。
类引索为5,父类引索6,因为没涉及接口因此为0,在cmd打印出的常量表可以查到:
解释一下#5#6后面的#21#22,这是指其值为对应第21、22项常量的值,21、22为utf8类型的字符串常量
此外class文件结构中还包括字段表集合、方法表集合、属性表集合。
本文为《深入理解java虚拟机》学习总结