深入理解Java Class结构

来源:互联网 发布:淘宝销量和评价 编辑:程序博客网 时间:2024/06/14 18:29

1. Class文件结构总览

Java能够跨平台主要靠虚拟机,而不同平台的虚拟机却能够运行同一份Class。这充分说明了Class文件才是Java跨平台的基石。
Class文件是一组8位字节为基础的二进制流,各个数据项目按照顺序紧凑排列在Class文件之中,中间没有任何分隔符,使得整个Class文件中存储的内容几乎全部都是程序运行的必要数据。
Class中只有两种数据类型:无符号数和表,无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数。表是有多个无符号数或其他表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾。下图给出了Class文件的概览:
这里写图片描述
下面伪代码给出了Class文件的结构:

ClassFile {    u4 magic;    u2 minor_version;    u2 major_version;    u2 constant_pool_count;    cp_info constant_pool[constant_pool_count - 1];    u2 access_flag;    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 atributes[attributes_count];}

下面对各个字段的含义进行详细描述。

2. 各个字段的描述

2.1 magic

魔数是一个4个字节的无符号整数,固定为0xCAFFBABE。使用软件WinHex可以打开Class文件查看魔数。
这里写图片描述

2.2 minor_version和major_version

minor_version和major_version分别是Class文件的小版本和大版本号,表示当前Class文件是有哪个版本的编译器编译产生的。下图给出了Class文件版本号和平台的对应关系。
这里写图片描述

2.3 constant_pool

constant_pool_count是常量池的数量,constant_pool是constant_pool_count个常量池表项。
常量池主要存放两大类常量:字面量和符号引用。字面量比较接近Java语言层面的常量概念,比如文本字符窜和被声明为final的常量值。而符号引用则属于编译原理方面的概念,包括如类和接口的全限定名、字段的名称和描述符、方法的名称和描述符。下图给出了常量池的项目类型:
这里写图片描述

2.4 access_flag

access_flag用于识别一些类或接口层次的访问信息,如这个Class是类还是接口,是否定义为public类型,是否定义为abstract类型;如果是类,是否被声明为final等等。下图给出了具体的标志位和标志位的含义:
这里写图片描述

2.5 this_class,super_class和interfaces

Class文件由这三项来确定这个类的继承关系。类索引和父类索引引用两个u2类型的索引值来表示,它们各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info类型的常量中的索引值可以找到定义在CONSTANT_Utf8_info类型的常量中的全限定名字符串。下图给出了类索引名查找全限定名的过程:
这里写图片描述

2.6 field_info

field_info描述接口或类中声明的变量。字段包含了类级别变量或实例级变量,但不包括方法内部声明的变量。字段表集合中不会列出从超类或父接口中继承而来的字段。下图给出了字段表的结构:
这里写图片描述

2.7 method_info

method_info描述接口或类中声明的方法,如果理解了字段表,那么方法表很好理解。方法表的结构如下:
这里写图片描述
方法的定义可以通过访问标志、名称索引、描述符索引表达清楚,但是方法体的方法呢?原来方法里的Java代码经过编译器编译成字节码指令之后,存放在方法属性表集合中一个名为”Code”的属性里面。如果弗雷方法在子类中没有被重写,方法表就不会产生来自父类的方法信息。

2.8 attribute_info

在Class文件、字段表、方法表中都可以携带自己的属性表集合,用来描述某些场景专有的信息。《Java虚拟机规范》预定了9项虚拟机实现应当能识别的属性:
这里写图片描述

参考资料
  • 《深入理解虚拟机》
  • 《实战Java虚拟机》
阅读全文
0 0
原创粉丝点击