1. class文件结构
1、Class文件是一组以8位字节为基础单位的二进制流
2、Class类伪结构有两种数据类型:无符号数和表
- 无符号数属于基本的数据类型,与u1、u2、u4、u8来分别表示1个字节、2个字节、4个字节和8个字节
- 表是由多个无符号或其他表作为数据项构成的复合数据类型
类型 | 名称 | 数量 |
---|---|---|
u4 | magic | 1 |
u2 | minor_version | 1 |
u2 | major_version | 1 |
u2 | constant_pool_count | 1 |
cp_info | constant_pool | 1 |
u4 | access_flags | 1 |
u4 | this_class | 1 |
u4 | super_class | 1 |
u4 | interfaces_count | 1 |
u4 | interfaces | 1 |
u4 | fields_count | 1 |
field_info | fields | 1 |
u4 | methods_count | 1 |
method_info | methods | 1 |
u4 | attributes_count | 1 |
attributes_info | attributes | 1 |
1. 1 魔术与class版本
范例class代码
package Selenium;
public class TestClass {
private int m;
public int inc() {
return m+1;
}
}
- 每个class文件的四个字节表示魔术(0xCAFEBABE)(咖啡宝贝?)
- 代表次版本号的第5个和第6个字节值为(0x0000)
- 主版本号的值为(0x0033),十进制表示51,51表示是JDK1.7编译的。
1.2 常量池
紧接着主版本号是常量池
常量池入口第一项为常量池容量计数值(constant_pool_count)(0x0016),十进制表示22,代表有21项常量(从0开始)
常量池之中主要存放两大类常量:字面量和(Literal)
字面量比较接近于java语言层面的常量概念 ,如文本字符串
符号引用用则属于编译原理方面的概念,包括了下面三大常量
- 类和接口的全限名称
- 字段的名称和描述符
- 方法的名称和描述符
常量池中的每一项常量都是一个表。
常量池的项目类型
类型 | 标志 | 描述 |
---|---|---|
CONSTANT_Utf8_info | 1 | UTF-8编码的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮点型字面量 |
CONSTANT_Long_info | 5 | 长整型字面量 |
CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
CONSTANT_Class_info | 7 | 类或接口的符号引用 |
CONSTANT_String_info | 8 | 字符串类型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
CONSTANT_Methodref_info | 10 | 类中的方法的符号引用 |
CONSTANT_InterfaceMethodref_info | 11 | 接口中的方法的符号引用 |
CONSTANT_NameAndType_info | 12 | 字段或方法的部分符号引用 |
CONSTANT_Class_info型常量结构
类型 | 名称 | 数量 |
---|---|---|
u1 | tag | 1 |
u2 | name_index | 1 |
0x07(十进制:7)表示tag标志,tag标志(7)在常量池的项目类型中指向CONSTANT_Class_info(参考:常量池的项目类型)
0x02(十进制:2)表示name_index,name_index表示第二项常量。
第二项常量的tag标志位是0x01(十进制:1),tag标志(1)在常量池的项目类型中指向CONSTANT_Utf8_info(参考:常量池的项目类型)。
CONSTANT_Utf8_info型常量结构
类型 | 名称 | 数量 |
---|---|---|
u1 | tag | 1 |
u2 | length | 1 |
u1 | bytes | length |
0x0012(十进制:12)表示CONSTANT_Utf8_info常量的长度。
53~73字节表示CONSTANT_Utf8_info常量的内容。
1.3 访问标志
在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志识别一些类或接口层次的访问信息
访问标志列表
标志名称 | 标志值 | 含义 |
---|---|---|
ACC_PUBLIC | 0X0001 | 是否为public |
ACC_FINAL | 0X0010 | 是否为被声明final,只有类可设置 |
ACC_SUPER | 0X0020 | 是否允许使用invokespecial字节码指令 |
ACC_INTERFACE | 0X0200 | 标志这是一个接口 |
ACC_ABSTRACT | 0X0400 | 是否为abstract类型 |
ACC_SYNTHETIC | 0X1000 | 标识这个类并非由用户代码产生 |
ACC_ANNOTATION | 0X0001 | 标识这是一个注解 |
ACC_ENNUM | 0X0001 | 标识这是一个枚举 |
总结:太理论了,太枯燥了,看不下去了。