目录
1.前序
2.总表
2.1class文件格式
2.2 常量池格式表
2.3 类访问标志
3.字段表
3.1 字段表结构
3.2 字段访问标识
3.3 描述符标识字符含义
4.方法表
4.1 方法表结构
4.2方法访问标识
4.3 属性表
本文主要针对jvm的字节码文件做一个字典类型的记录,方便以后学习使用。本文所有的表格均出自《深入理解Java虚拟机》这本书的第六章内容。
另外,对于一个class文件,jvm提供了一个命令,对其进行反编译,他便是"javap -v. classs文件"通过这个命令,你还发现在字节码的世界里有需要许多不为人知的秘密。
类型 |
名称 |
数量 |
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 |
surper_class |
1 |
u2 |
interfaces_count |
1 |
u2 |
interfaces |
interface_count |
u2 |
fields_count |
1 |
field_info |
fields |
fields_count |
u2 |
methods_count |
1 |
method_info |
methods |
methods_count |
u2 |
attributes_count |
1 |
attribute_info |
attributes |
attributes_count |
常量 |
项目 |
类型 |
描述 |
CONSTANT_Utf8_info |
tag |
u1 |
值为1 |
length |
u2 |
UTF-8编码的字符串占用的字节数 |
|
bytes |
u1 |
长度为length的UTF-8编码的字符串 |
|
CONSTANT_Integer_info |
tag |
u1 |
值为3 |
bytes |
u4 |
按照高位在前存储的int值 |
|
CONSTANT_Float_info |
tag |
u1 |
值为4 |
bytes |
u4 |
按照高位在前存储的float值 |
|
CONSTANT_Long_info |
tag |
u1 |
值为5 |
bytes |
u8 |
按照高位在前存储的long值 |
|
CONSTANT_Double_info |
tag |
u1 |
值为6 |
bytes |
u8 |
按照高位在前存储的double值 |
|
CONSTANT_Class_info |
tag |
u1 |
值为7 |
index |
u2 |
指向全限定名常量项的索引 |
|
CONSTANT_String_info |
tag |
u1 |
值为8 |
index |
u2 |
指向字符串字面量的索引 |
|
CONSTANT_Fieldref_info |
tag |
u1 |
值为9 |
index |
u2 |
指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项 |
|
index |
u2 |
指向字段描述符CONSTANT_NameAndType的索引项 |
|
CONSTANT_Methodref_info |
tag |
u1 |
值为10 |
index |
u2 |
指向声明方法的类或者接口描述符CONSTANT_Class_info的索引项 |
|
index |
u2 |
指名称及类型CONSTANT_NameAndType的索引项 |
|
CONSTANT_InterfaceMethodref_info |
tag |
u1 |
值为11 |
index |
u2 |
指向声明方法的接口描述符CONSTANT_Class_info的索引项 |
|
index |
u2 |
指名称及类型CONSTANT_NameAndType的索引项 |
|
CONSTANT_NameAndType_info |
tag |
u1 |
值为12 |
index |
u2 |
指向该字段或方法名称常量项的索引 |
|
index |
u2 |
指向该字段或方法描述符常量项的索引 |
|
CONSTANT_MethodHandle_info |
tag |
u1 |
值为15 |
reference_kind |
u1 |
值必须在1-9之间(包括1和9),它决定了方法句柄的类型,方法句柄类型的值表示方法句柄的字节码行为 |
|
reference_index |
u2 |
值必须是对常量池的有效索引 |
|
CONSTANT_MethodType_info |
tag |
u1 |
值为16 |
descriptor_index |
u2 |
值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf-8_info结构,表示方法的描述符 |
|
CONSTANT_Invoke-Dynamic_info |
tag |
u1 |
值为18 |
bootstrap_method_attr_index |
u2 |
值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引 |
|
name_and_type_index |
u2 |
值必须是对当前常量池的有效索引,常量池在该所引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符 |
|
注: 1.由于常量个数不固定,所以需要放置一个u2格式的数据; 2.他其他容量计数器不同的是,常量基数从1开始,也许是null的引用(仅仅猜测) 3.常量池主要包含字面量和符号引用。字面量接近于java层面的常量概念;符号引用则属于编译原理方面概念(类和接口的全限定名、字段名称和描述符、方法的名称和描述符)。 |
标志名称 |
标志量 |
含义 |
ACC_PULIC |
0x0001 |
是否为public类型 |
ACC_FINAL |
0x0010 |
是否被声明为final,只有类可设置 |
ACC_SUPER |
0x0020 |
是否允许使用invokesecial字节码指令的新语意,invokespecial指令的语意在JDK1.0.2发生过改变,为了区别这了指令使用哪种语意,JDK1.0.2之后编译出来的类的这个标志都必须为真。 |
ACC_INTERFACE |
0x0200 |
标识这是一个接口 |
ACC_ABSTRACT |
0x0400 |
是否abstract类型,对于接口或者抽象类来说,此标志值为真,其他类型为假 |
ACC_SYNTHERIC |
0x1000 |
标识这个类并非由用户代码产生的 |
ACC_ANNOTATION |
0x2000 |
标识这是个注解 |
ACC_ENUM |
0x4000 |
标识这是个枚举 |
类型 |
名称 |
数量 |
u2 |
access_flags |
1 |
u2 |
name_index |
1 |
u2 |
descriptor_index |
1 |
u2 |
attributes_count |
1 |
attribute_info |
attributes |
attributes_count |
标志名称 |
标志值 |
含义 |
ACC_PUBLIC |
0x0001 |
字段是否public |
ACC_PRIVATE |
0x0002 |
字段是否private |
ACC_PROTECTED |
0x0004 |
字段是否protected |
ACC_STATIC |
0x0008 |
字段是否static |
ACC_FINAL |
0x0010 |
字段是否final |
ACC_VOLATILE |
0x0040 |
字段是否volatile |
ACC_TRANSIENT |
0x0080 |
字段是否transient |
ACC_SYNTHETIC |
0x1000 |
字段是否由编译器自动产生的 |
ACC_ENUM |
0x4000 |
字段是否enum |
标识字符 |
含义 |
标识字符 |
含义 |
B |
基本类型byte |
J |
基本类型long |
C |
基本类型char |
S |
基本类型short |
D |
基本类型double |
Z |
基本类型boolean |
F |
基本类型float |
V |
特殊类型void |
I |
基本类型int |
L |
对象类型,如Ljava/lang/Object |
注: 对于数组类型,每一维度将使用一个前置的“[”字符来描述,如一个定义为“java.lang.String[][]”类型的二维数组,将被记录为“[[java/lang/String”,一个整型数组“int[]”将被记录为“[I” |
类型 |
名称 |
数量 |
u2 |
access_flags |
1 |
u2 |
name_index |
1 |
u2 |
descriptor_index |
1 |
u2 |
attributes_count |
1 |
attribute_info |
attributes |
attributes_count |
标志名称 |
标志值 |
含义 |
ACC_PUBLIC |
0x0001 |
方法是否public |
ACC_PRIVATE |
0x0002 |
方法是否private |
ACC_PROTECTED |
0x0004 |
方法是否protected |
ACC_STATIC |
0x0008 |
方法是否static |
ACC_FINAL |
0x0010 |
方法是否final |
ACC_SYNCHRONIZED |
0x0020 |
方法是否synchronized |
ACC_BRIDGE |
0x0040 |
方法是否由编译器产生的桥接方法 |
ACC_VARARGS |
0x0080 |
方法是否接受不定参数 |
ACC_NATIVE |
0x0100 |
方法是否为native |
ACC_ABSTRACT |
0x0400 |
方法是否abstract |
ACC_STRICTFP |
0x0800 |
方法是否为strictfp |
ACC_SYNTHETIC |
0x1000 |
方法是否由编译器自动产生的 |
1)Code属性表的结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
max_stack |
1 |
u2 |
max_locals |
1 |
u4 |
code_length |
1 |
u1 |
code |
code_length |
u2 |
exception_table_length |
1 |
exception_info |
exception_table |
exception_table_length |
u2 |
attributes_count |
1 |
attribute_info |
attributes |
attributes_count |
2)异常表的属性结构
类型 |
名称 |
数量 |
u2 |
start_pc |
1 |
u2 |
end_pc |
1 |
u2 |
handler_pc |
1 |
u2 |
catch_pc |
1 |
3)Exception属性结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
number_of_exceptions |
1 |
u2 |
exception_index_table |
number_of_exceptions |
4)LineNumberTable属性结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
line_number_table_length |
1 |
line_number_info |
line_number_table |
line_number_table_length |
注: line_number_table是一个数量为line_number_table_length、类型为line_number_info的集合,line_number_info表包含了start_pc和line_number两个u2类型的数据项,前者是字节码行号,后者是java源码行号。 |
5)LocalVariableTable属性结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
local_variable_table_length |
1 |
local_variable_info |
local_variable_table |
local_variable_table_length |
6)local_variable_info项目结构
类型 |
名称 |
数量 |
u2 |
start_pc |
1 |
u2 |
length |
1 |
u2 |
name_index |
1 |
u2 |
descriptor_index |
1 |
u2 |
index |
1 |
7)SourceFile属性结构表
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
sourcefile_index |
1 |
8)ConstantValue属性结构表
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
constantvalue_index |
1 |
9)InnerClasses属性结构表
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
number_of_classes |
1 |
inner_classes_info |
inner_classes |
number_of_classes |
10)inner_classes_info表的结构
类型 |
名称 |
数量 |
u2 |
inner_class_info_index |
1 |
u2 |
outer_class_info_index |
1 |
u2 |
inner_name_index |
1 |
u2 |
inner_class_access_flags |
1 |
11)inner_class_access_flags标志
标志名称 |
标志值 |
含义 |
ACC_PUBLIC |
0x0001 |
内部类是否public |
ACC_PRIVATE |
0x0002 |
内部类是否private |
ACC_PROTECTED |
0x0004 |
内部类是否protected |
ACC_STATIC |
0x0008 |
内部类是否static |
ACC_FINAL |
0x0010 |
内部类是否final |
ACC_INTERFACE |
0x0020 |
内部类是否synchronized |
ACC_ABSTRACT |
0x0400 |
内部类是否abstract |
ACC_SYNTHETIC |
0x1000 |
内部类是否由编译器自动产生的 |
ACC_ANNOTATION |
0x2000 |
内部类是否是一个注解 |
ACC_ENUM |
0x4000 |
内部类是否是一个枚举 |
12)Deprecated及Synthetic属性结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
13)StackMapTable 属性的结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
number_of_entries |
1 |
stack_map_frame |
stack_map_frame_entries |
number_of_entries |
14)Signature属性的结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
signature_index |
1 |
15)BootstrapMethods属性结构
类型 |
名称 |
数量 |
u2 |
attribute_name_index |
1 |
u4 |
attribute_length |
1 |
u2 |
num_bootstrap_methods |
1 |
Bootstrap-method |
bootstrap_methods |
num_bootstrap_methods |
16)bootstrap_method属性的结构
类型 |
名称 |
数量 |
u2 |
bootstrap_method_ref |
1 |
u2 |
num_bootstrap_arguments |
1 |
u2 |
bootstrap_arguments |
num_bootstrap_arguments |