简单记录.Class文件结构
ClassFile总体结构
1 | ClassFile { |
magic
标识是否是class文件,正常class文件开头都是4个字节0xCAFEBABE.
minor_version major_version
编译成class文件的版本号,java6编译的major_version是0x32.
constant_pool_count
常量池的数量。
constant_pool
常量池,用于存放不同类型的数据,各种字符串,变量名称,变量类型都会存储在常量池。
1
2
3
4cp_info {
u1 tag;
u1 info[];
}| Constant Type | Value |
| —————————– | —– |
| CONSTANT_Class | 7 |
| CONSTANT_Fieldref | 9 |
| CONSTANT_Methodref | 10 |
| CONSTANT_InterfaceMethodref | 11 |
| CONSTANT_String | 8 |
| CONSTANT_Integer | 3 |
| CONSTANT_Float | 4 |
| CONSTANT_Long | 5 |
| CONSTANT_Double | 6 |
| CONSTANT_NameAndType | 12 |
| CONSTANT_Utf8 | 1 |
| CONSTANT_MethodHandle | 15 |
| CONSTANT_MethodType | 16 |
| CONSTANT_InvokeDynamic | 18 |access_flags
指定接口和类的访问权限。
| Flag Name | Value | Interpretation |
| ————- | ———-| —————————————————–|
| ACC_PUBLIC | 0x0001 | 公共,可以被外部包访问。 |
| ACC_FINAL | 0x0010 | 不允许继承. |
| ACC_SUPER | 0x0020 | 当被invoke.指令调用时,要特别对待超类方法。 |
| ACC_INTERFACE | 0x0200 | 接口类。 |
| ACC_ABSTRACT | 0x0400 | 抽象类,不能实例化。 |
| ACC_SYNTHETIC | 0x1000 | 编译器生成,不在源代码中。 |
| ACC_ANNOTATION| 0x2000 | 注解类型。 |
| ACC_ENUM | 0x4000 | 枚举类型。 |this_class
指向的是在静态区的CONSTANT_class_info结构体,说明当前的类名称。
super_class
0 或者 指向的是在静态区的CONSTANT_class_info结构体,说明当前的父类名称。
interfaces_count
说明接口的数量
interfaces
指向CONSTANT_class_info数组,记录当前类的实现接口。
fields_count
字段数量
fields
字段信息。
1
2
3
4
5
6
7field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}| Flag Name | Value | Interpretation |
| ————- | ——— | —————————————— |
| ACC_PUBLIC | 0x0001 | pubilc,包外可访问。 |
| ACC_PRIVATE | 0x0002 | private,只可在类内访问。 |
| ACC_PROTECTED | 0x0004 | protected,类内和子类中可访问。 |
| ACC_STATIC | 0x0008 | static. 静态。 |
| ACC_FINAL | 0x0010 | final. 常量。 |
| ACC_VOLATILE | 0x0040 | 易变类型。 |
| ACC_TRANSIENT | 0x0080 | 序列化忽略。 |
| ACC_SYNTHETIC | 0x1000 | 编译器产生。 |
| ACC_ENUM | 0x4000 | 枚举类型。 |methods_count
方法数量
methods
方法信息。
1
2
3
4
5
6
7method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}| Flag Name | Value | Interpretation |
| - | - | - |
| ACC_PUBLIC | 0x0001 | 公共方法
| ACC_PRIVATE | 0x0002 | 私有方法
| ACC_PROTECTED | 0x0004 | 保护方法
| ACC_STATIC | 0x0008 | 静态方法
| ACC_FINAL | 0x0010 | 不允许重写
| ACC_SYNCHRONIZED | 0x0020 | Declared synchronized; invocation is wrapped by a monitor use.
| ACC_BRIDGE | 0x0040 | 编译器生成
| ACC_VARARGS | 0x0080 | 可变参数
| ACC_NATIVE | 0x0100 | Native方法
| ACC_ABSTRACT | 0x0400 | 抽象方法
| ACC_STRICT | 0x0800 | 浮点数模型2.8.2
| ACC_SYNTHETIC | 0x1000 | 编译器生成方法attributes_count
属性数量
attributes
属性信息
静态区结构体
CONSTANT_Class_info 代表接口或者类
1
2
3
4CONSTANT_Class_info {
u1 tag; // 7
u2 name_index; // 指向静态区的CONSTANT_Utf8_info存储名称。
}CONSTANT_Fieldref_info 用于记录字段信息
1
2
3
4
5CONSTANT_Fieldref_info {
u1 tag; // 9
u2 class_index; // 指向的可能是classtype或者interfacetype
u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
}CONSTANT_Methodref_info 用于记录方法信息
1
2
3
4
5CONSTANT_Methodref_info {
u1 tag; // 10
u2 class_index; // classtype
u2 name_and_type_index; // 如果是<开始的,那么一定是void <init>的方法
}CONSTANT_InterfaceMethodref_info 用于记录接口中的方法信息
1
2
3
4
5CONSTANT_InterfaceMethodref_info {
u1 tag; // 11
u2 class_index; // interfacetype
u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
}CONSTANT_String_info 记录字符串。
1
2
3
4CONSTANT_String_info {
u1 tag; // 8
u2 string_index; // 指向CONSTANT_Utf8_info
}CONSTANT_Integer_info 记录Int类型常量
1
2
3
4CONSTANT_Integer_info {
u1 tag; // 3
u4 bytes; // 整型常量
}CONSTANT_Float_info 记录浮点数常量
1
2
3
4CONSTANT_Float_info {
u1 tag; // 4
u4 bytes; // 浮点常量
}几个特殊值:
0x7f800000 => Float.POSITIVE_INFINITY
0xff800000 => Float.NEGATIVE_INFINITY
0x7f800001 to 0x7fffffff => Float.NaN
0xff800001 to 0xffffffff => Float.NaN
CONSTANT_Long_info 记录long类型常量
1
2
3
4
5CONSTANT_Long_info {
u1 tag; // 5
u4 high_bytes; // 高4位
u4 low_bytes; // 低4位
}
CONSTANT_Double_info 记录Double类型常量
1
2
3
4
5CONSTANT_Double_info {
u1 tag; // 6
u4 high_bytes; // 双精度浮点的高四位值
u4 low_bytes; // 双精度浮点的低四位值
}几个特殊值:
0x7ff0000000000000L => Double.POSITIVE_INFINITY
0xfff0000000000000L => Double.NEGATIVE_INFINITY
0x7ff0000000000001L to 0x7fffffffffffffffL => Double.NaN
0xfff0000000000001L to 0xffffffffffffffffL => Double.NaN
CONSTANT_NameAndType_info 记录方法或字段的名称(name)和描述符(descriptor)
1
2
3
4
5CONSTANT_NameAndType_info {
u1 tag; // 12
u2 name_index; // CONSTANT_Utf8_info
u2 descriptor_index; // CONSTANT_Utf8_info
}CONSTANT_Utf8_info 记录字符串。
1
2
3
4
5CONSTANT_Utf8_info {
u1 tag; // 1
u2 length; // 长度
u1 bytes[length]; // 字符串数据。
}CONSTANT_MethodHandle_info 代表方法句柄
1
2
3
4
5CONSTANT_MethodHandle_info {
u1 tag; // 15
u1 reference_kind; // 1-9的值
u2 reference_index; // 不同的reference_kind值有不同的行为。
}CONSTANT_MethodType_info
1
2
3
4CONSTANT_MethodType_info {
u1 tag; // 16
u2 descriptor_index; // CONSTANT_Utf8_info
}CONSTANT_InvokeDynamic_info
1
2
3
4
5CONSTANT_InvokeDynamic_info {
u1 tag; // 17
u2 bootstrap_method_attr_index;
u2 name_and_type_index;
}