1、class文件的结构:
2、常量池:
Constant_pool[constant_pool_count-1]: 常量池, 常量池包含字符串常量、类名、接口名、字段名.
Constant_pool是表结构,表结构(_info)有若干个项(item)构成。常量池中的项的结构:
cp_info{
u1 tag
u2 info[]
} //u:unsigned int
tag表如下:
每个常量的结构:
CONSTANT_Class_info{
u1 tag //tag=7
u2 name_index // name_index是索引值,指向CONSTANT_Utf8_info
}
CONSTANT_Fieldref_info{
u1 tag //9
u2 class_index //指向CONSTANT_Class_info;既可以表示类、也可以表示接口
u2 name_and_type_index //指向CONSTANT_NameAndType,表示字段名、字段描述符
}
CONSTANT_Methodref_info{
u1 tag //10
u2 class_index //指向CONSTANT_Class_info;表示类
u2 name_and_type_index //指向CONSTANT_NameAndType,表示方法名、方法描述符
}
CONSTANT_InterfaceMethodref_info{
u1 tag //11
u2 class_index //指向CONSTANT_Class_info;表示接口
u2 name_and_type_index //指向CONSTANT_NameAndType_info,表示方法名、方法描述符
}
CONSTANT_String_info{
u1 tag // 8
u2 string_index //指向CONSTANT_Utf8_info
}
CONSTANT_Integer_info{
u1 tag //3
u4 bytes //int 常量值
}
CONSTANT_Float_info{
u1 tag //4
u4 bytes //float 常量值
}
CONSTANT_Long_info{
u1 tag //5
u4 high_bytes
u4 low_bytes // high_bytes、low_bytes共同表示8个字节的long常量
}
CONSTANT_Double_info{
u1 tag //6
u4 high_bytes
u4 low_bytes // high_bytes、low_bytes共同表示8个字节的long常量
}
CONSTANT_NameAndType{
u1 tag //12
u2 name_index //指向CONSTANT_Utf8_info,表示名称
u2 descriptor_index //指向CONSTANT_Utf8_info,表示描述符
}
CONSTANT_Utf8_info{
u1 tag //1
u2 length
u1 bytes[length] //长度为length的字符串数组
}
CONSTANT_MethodHandle_info{
u1 tag // 15
u1 reference_kind //取值1~9,表示方法句柄类型
u2 reference_index //可以指向CONSTANT_Fieldref_info、CONSTANT_Methodref_info、CONSTANT_InterfaceMethodref_info
}
CONSTANT_MethodType_info{
u1 tag //16
u2 descriptor_index //指向CONSTANT_Utf8_info
}
CONSTANT_InvokeDynamic_info{
u1 tag //18
u2 bootstrap_method_attr_index //对bootstrap_methods数组的索引
u2 name_and_type_index //指向CONSTANT_NameAndType_info
}
3、access_flags:表示字段的访问权限,属性。
4、字段
每个字段都用field_info表示:
field_info{
u2 access_flags //表示字段的访问权限、属性
u2 name_index //对常量池的索引
u2 descriptor_index //对常量池的索引
u2 attributes_count //附加属性的数量
attribute_info attributes[attributes_count] //每个成员是attribute_info结构
}
5、方法
method_info{
u2 access_flags //表示方法的访问权限、属性
u2 name_index //对常量池的索引
u2 descriptor_index //对常量池的索引
u2 attributes_count//附加属性的数量
attribute_info attributes[attributes_count] //每个成员是attribute_info结构
}
6、属性
attribute_info{
u2 attribute_name_index //常量池索引
u4 attribute_length
u1 info[attribute_length]
}
虚拟机定义了23个属性,每个属性都有其结构。
Code属性:
Code_attribute{
u2 attribute_name_index
u4 attribute_length
u2 max_stack //操作数栈深度的最大值
u2 max_locals //局部变量的个数
u4 code_length //code[]所占的字节数
u1 code[code_length] //字节码指令
u2 exception_table_length
{ u2 start_pc
u2 end_pc //start、end表示code[]异常处理的范围
u2 handler_pc //异常处理起点
u2 catch_type //对常量池的引用
}exception_table[exception_table_length] //code[]中的异常处理器
u2 attribute_count
attribute_info attributes[attributes_count]
}
7、解析一段字节码:
package org.fenixsoft.clazz;
public class TestClass{
private int m;
public int inc(){
return m+1;
}
}
编译后的class文件:
00000000h: CA FE BA BE 00 00 00 34 00 13 0A 00 04 00 0F 09 ; 漱壕…4……..
00000010h: 00 03 00 10 07 00 11 07 00 12 01 00 01 6D 01 00 ; ………….m..
00000020h: 01 49 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 ; .I……()
00000030h: 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E ; V…Code…LineN
00000040h: 75 6D 62 65 72 54 61 62 6C 65 01 00 03 69 6E 63 ; umberTable…inc
00000050h: 01 00 03 28 29 49 01 00 0A 53 6F 75 72 63 65 46 ; …()I…SourceF
00000060h: 69 6C 65 01 00 0E 54 65 73 74 43 6C 61 73 73 2E ; ile…TestClass.
00000070h: 6A 61 76 61 0C 00 07 00 08 0C 00 05 00 06 01 00 ; java…………
00000080h: 1D 6F 72 67 2F 66 65 6E 69 78 73 6F 66 74 2F 63 ; .org/fenixsoft/c
00000090h: 6C 61 7A 7A 2F 54 65 73 74 43 6C 61 73 73 01 00 ; lazz/TestClass..
000000a0h: 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 ; .java/lang/Objec
000000b0h: 74 00 21 00 03 00 04 00 00 00 01 00 02 00 05 00 ; t.!………….
000000c0h: 06 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 ; …………….
000000d0h: 00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ………..*?.?
000000e0h: 00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 03 ; …………….
000000f0h: 00 01 00 0B 00 0C 00 01 00 09 00 00 00 1F 00 02 ; …………….
00000100h: 00 01 00 00 00 07 2A B4 00 02 04 60 AC 00 00 00 ; ……*?..`?..
00000110h: 01 00 0A 00 00 00 06 00 01 00 00 00 07 00 01 00 ; …………….
00000120h: 0D 00 00 00 02 00 0E ; …….
分析:
0013:共有18个常量成员
0A 00 04 00 0F :CONSTANT_Methodref,
4 CONSTANT_Class
15 CONSTANT_NameAndType
09 00 03 00 10: CONSTANT_Fieldref
3 CONSTANT_Class
16 CONSTANT_NameAndType
07 00 11:CONSTANT_Class
17 CONSTANT_Utf8_info
07 00 12:CONSTANT_Class
18 CONSTANT_Utf8_info
01 00 01 6D:CONSTANT_Utf8_info
length=1
6D:m
01 00 01 49: CONSTANT_Utf8_info
length=1
49:I
01 00 06 3C 69 6E 69 74 3E: CONSTANT_Utf8_info
01 00 03 28 29 56: CONSTANT_Utf8_info
01 00 04 43 6F 64 65:CONSTANT_Utf8_info
01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 :CONSTANT_Utf8_info
01 00 03 69 6E 63:CONSTANT_Utf8_info
01 00 03 28 29 49:CONSTANT_Utf8_info
01 00 0A 53 6F 75 72 63 65 46 69 6C 65:CONSTANT_Utf8_info
01 00 0E 54 65 73 74 43 6C 61 73 73 2E 6A 61 76 61:CONSTANT_Utf8_info
0C 00 07 00 08 :CONSTANT_NameAndType
7 CONSTANT_Utf8_info
8 CONSTANT_Utf8_info
0C 00 05 00 06:CONSTANT_NameAndType
5 CONSTANT_Utf8_info
6 CONSTANT_Utf8_info
01 00 1D 6F 72 67 2F 66 65 6E 69 78 73 6F 66 74 2F 63 6C 61 7A 7A 2F 54 65 73 74
43 6C 61 73 73:CONSTANT_Utf8_info
01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 :CONSTANT_Utf8_info
00 21 : access_flags ACC_PUBLIC | ACC_SUPER
00 03 :this_class :指向第三个常量池成员,第三个常量池成员又指向第17个成员
org/fenixsoft/clazz/TestClass
00 04 :super_class: java/lang/Object
00 00 :interfaces_count :没有实现接口
00 01 : fields_count
00 02 00 05 00 06 00 00:field_info
00 02 :methods_count
00 01 00 07 00 08 00 01 : method_info (00 01:attributes_count)
attribute_info:
00 09 00 ; …………….
00 00 1D 00 01 00 01 00 00 00 05 2A B7 00 01 B1 ; ………..*?.?
00 00 00 01 00 0A 00 00 00 06 00 01 00 00 00 03 ; …………….
00 01 00 0B 00 0C 00 01 00 09 00 00 00 1F 00 02 ; …………….
00 01 00 00 00 07 2A B4 00 02 04 60 AC 00 00 00 ; ……*?..`?..
01 00 0A 00 00 00 06 00 01 00 00 00 07 00 01 00 ; …………….
0D 00 00 00 02 00 0E
另外,可以cmd下使用> javap -verbose class文件名 进行解析。