java能将一个类编译成字节码,然后放到虚拟机上执行。
class文件格式
Class文件是一组以8位字节为基础单位的二进制流,各个数据项按顺序紧密的从前向后排列。我们可以将class文件看做一个巨大的结构体,这个类的所有信息全部都在这儿,类似于json。
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];
}
method_info methods[methods_count];
这是指里面有一个方法数组,这个数组里面包含的这个类所有方法的信息,这个数组的每一项都是method_info
这也是结构体,里面包含了一个方法的所有信息。
这是 method_info
结构体的定义伪码
method_info {
u2 access_flags;
u2 name_index;//方法名
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
attributes包含了方法各方面的属性,代码属性也在里面。虽然这里看似是数组形式,实际上每个属性大小应该不一样,所以这里的attributes应该是个包含很多属性的结构体。
Code_attribute {
u2 attribute_name_index;
u4 attribute_length;
u2 max_stack;
u2 max_locals;
u4 code_length;
u1 code[code_length];
u2 exception_table_length;
{ u2 start_pc;
u2 end_pc;
u2 handler_pc;
u2 catch_type;
} exception_table[exception_table_length];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
方法体的二进制代码就在code数组里面。
这里的二进制代码可以就是java的字节码,可以理解为一种平台无关的汇编语言。虚拟机负责将这种汇编翻译成为真正的机器语言。
class的常量池
用来存放类中用到的字符串常量,类名,接口名,方法名,以及实例成员名等等。
参考:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.3
https://zh.wikipedia.org/wiki/Java%E5%AD%97%E8%8A%82%E7%A0%81
来源:CSDN
作者:yrk0556
链接:https://blog.csdn.net/yrk0556/article/details/104080579