字节码
字节码文件
文件格式
Java编译后的字节码文件格式,其文件结构定义如下:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
以下面一个最简单的一个类为例,在下面这个类中,只通过class修饰定义了一个类,其中没有定义任何常亮,变量以及方法:
class SimpleClass { }编译
魔数(magic):
4bytes, 0xCAFEBABE
版本(version):
包括主版本号和小版本号
小版本号(minor version):
2bytes,0x0000
主版本号(major version):
2bytes,0x0034
常量池:
常量池通过一个数组来保存各个常量,数组的大小-1就是常量池常量个数。针对不同类型的常量通过tag来表示。
常量池常量个数(constant pool count):
0x000D,转换为10进制就是13,
常量池(constant pool):
常量tag:
0x0A,表示一个CONSTANT_Methodref类型的常量
class_index:
0x0003,
name_and_type_index:
0x000A
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000B,
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000C
常量tag:
0x01, 表示一个CONSTANT_Utf8类型的常量
length:
0x0006, 表示字符串长度
bytes[length]:
0x3C696E69743E,表示字符串“<init>”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0003,表示字符串长度
bytes[length]:
0x282956,表示字符串“()V”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0004,表示字符串长度
bytes[length]:
0x436F6465,表示字符串“Code”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000F,表示字符串长度
bytes[length]:
0x4C696E654E756D6265725461626C65,表示字符串“LineNumberTable”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000A,表示字符串长度
bytes[length]:
0x536F7572636546696C65,表示字符串“SourceFile”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x53696D706C65436C6173732E6A617661,表示字符串“SimpleClass.java”
常量tag:
0x0C,表示一个CONSTANT_NameAndType类型的常量
name_index:
0x0004,
descriptor_index:
0x0005,
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000B, 表示字符串长度
bytes[length]:
0x53696D706C65436C617373,表示字符串“SimpleClass”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x6A6176612F6C616E672F4F626A656374,表示字符串“java/lang/Object”
访问控制修饰标志(access_flags):
0x0020
this_class:
0x0002
super_class:
0x0003
interfaces_count:
0x0000
interfaces[interfaces_count]:
fields_count:
0x0000
fields[fields_count]:
methods_count:
0x0001
methods[methods_count]:
方法:
access_flags:
0x0000
name_index:
0x0004
descriptor_index:
0x0005
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0006
attribute_length:
0x0000001D,表示29
info[attribute_length]:
0x00010001000000052AB70001B100000001000700000006000100000001
对info[attribute_length]的说明:Code_attribute
attribute_name_index:
就是上面对应的attribute_name_index:0x0006
attribute_length:
就是上面对应的attribute_length:0x0000001D,表示29
max_stack:
0x0001
max_locals:
0x0001
code_length:
0x00000005
code[code_length]:
0x2AB70001B1
从这里可以看出这个方法对应的代码指令就是:0x2AB70001B1,具体是些什么指令呢?
经过分析的结果就是:
0: aload_0 1: invokespecial #1 4: return
前面的数字表示对应的指令所占用的字节数,加起来正好5个字节。aload_0对应0x2A,invokespecial #1对应0xB70001,其中0xB7就表示invokespecial指令,return对应0xB1。这里主要就是调用了Object的无参构造方法,然后返回。
exception_table_length:
0x0000
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length]:
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0007
attribute_length:
0x00000006
info[attribute_length]:
0x000100000001
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0008
attribute_length:
0x00000002
info[attribute_length]:
0x0009
到这里整个字节码class文件就全部分析完了。
参考文章:Chapter 4. The class File Format,https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html
字节码
字节码文件
文件格式
Java编译后的字节码文件格式,其文件结构定义如下:
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
以下面一个最简单的一个类为例,在下面这个类中,只通过class修饰定义了一个类,其中没有定义任何常亮,变量以及方法:
class SimpleClass { }编译 反汇编如下:
魔数(magic):
4bytes, 0xCAFEBABE
版本(version):
包括主版本号和小版本号
小版本号(minor version):
2bytes,0x0000
主版本号(major version):
2bytes,0x0034
常量池:
常量池通过一个数组来保存各个常量,数组的大小-1就是常量池常量个数。针对不同类型的常量通过tag来表示。
常量池常量个数(constant pool count):
0x000D,转换为10进制就是13,
常量池(constant pool):
常量tag:
0x0A,表示一个CONSTANT_Methodref类型的常量
class_index:
0x0003,
name_and_type_index:
0x000A
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000B,
常量tag:
0x07,表示一个CONSTANT_Class类型的常量
name_index:
0x000C
常量tag:
0x01, 表示一个CONSTANT_Utf8类型的常量
length:
0x0006, 表示字符串长度
bytes[length]:
0x3C696E69743E,表示字符串“<init>”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0003,表示字符串长度
bytes[length]:
0x282956,表示字符串“()V”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0004,表示字符串长度
bytes[length]:
0x436F6465,表示字符串“Code”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000F,表示字符串长度
bytes[length]:
0x4C696E654E756D6265725461626C65,表示字符串“LineNumberTable”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000A,表示字符串长度
bytes[length]:
0x536F7572636546696C65,表示字符串“SourceFile”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x53696D706C65436C6173732E6A617661,表示字符串“SimpleClass.java”
常量tag:
0x0C,表示一个CONSTANT_NameAndType类型的常量
name_index:
0x0004,
descriptor_index:
0x0005,
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x000B, 表示字符串长度
bytes[length]:
0x53696D706C65436C617373,表示字符串“SimpleClass”
常量tag:
0x01,表示一个CONSTANT_Utf8类型的常量
length:
0x0010,表示字符串长度
bytes[length]:
0x6A6176612F6C616E672F4F626A656374,表示字符串“java/lang/Object”
访问控制修饰标志(access_flags):
0x0020
this_class:
0x0002
super_class:
0x0003
interfaces_count:
0x0000
interfaces[interfaces_count]:
fields_count:
0x0000
fields[fields_count]:
methods_count:
0x0001
methods[methods_count]:
方法:
access_flags:
0x0000
name_index:
0x0004
descriptor_index:
0x0005
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0006
attribute_length:
0x0000001D,表示29
info[attribute_length]:
0x00010001000000052AB70001B100000001000700000006000100000001
对info[attribute_length]的说明:Code_attribute
attribute_name_index:
就是上面对应的attribute_name_index:0x0006
attribute_length:
就是上面对应的attribute_length:0x0000001D,表示29
max_stack:
0x0001
max_locals:
0x0001
code_length:
0x00000005
code[code_length]:
0x2AB70001B1
从这里可以看出这个方法对应的代码指令就是:0x2AB70001B1,具体是些什么指令呢?
经过分析的结果就是:
0: aload_0 1: invokespecial #1 4: return
前面的数字表示对应的指令所占用的字节数,加起来正好5个字节。aload_0对应0x2A,invokespecial #1对应0xB70001,其中0xB7就表示invokespecial指令,return对应0xB1。这里主要就是调用了Object的无参构造方法,然后返回。
exception_table_length:
0x0000
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length]:
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0007
attribute_length:
0x00000006
info[attribute_length]:
0x000100000001
attributes_count:
0x0001
attributes[attributes_count]:
attribute_name_index:
0x0008
attribute_length:
0x00000002
info[attribute_length]:
0x0009
到这里整个字节码class文件就全部分析完了。
参考文章:Chapter 4. The class File Format,https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html