前言
以前计算机程序课上老师总说:计算机只认识0和1,写的程序都会编译成为0和1组成的二进制格式才能被计算机执行。然而10多年的时间过去了,今天的计算机仍然只能识别0和1,但是建立在虚拟机之上的大量程序语言发展迅速,将2我们编写的程序编译成二进制本地机器码(native code)已不再是唯一的选择,越来越多的程序语言选择了与操作系统和机器指令无关平台中立的格式作为程序编译之后的存储格式。这也是Java这类语言,平台无关性的基石。而且虚拟机上更有语言无关性的趋势。
Class类文件的结构
Class文件是一组以8位字节为基础的二进制,各个数据项目严格按照顺序紧凑的排列Class文件之间,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部都是程序运行的必要数据。
虚拟机规范:Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中还有两种数据结构:无符号和表,后面的解析都要以这两种数据类型为基础。
无符号数属于基本的数据类型,用u1,u2,u4,u8分别代表1个字节、2个字节、4个字节、8个字节的无符号数,可以用来描述数字、索引引用、数量值,或者按照UTF-8编码构成字符串值。
表是由多个无符号数或其他数据项构成的复合结构数据,整个class文件本质上就是一张表。
魔数
每个class文件的头四个字节被称为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。很多图片格式在文件头都有魔数。Java中为:0XCAFFBABE;
版本号
紧接着4个字节存储的是Class文件的版本号:5-6是次版本,7-8是主版本。
常量池
主次版本号之后是常量池的入口,也是与其他项目关联最多的数据类型,也是占用class文件空间最大的项目之一,同时还是第一个出现的表类型。主要存放字面量和引用。
访问标志
在常量池之后,紧接2个字节代表访问标志,包括是接口还是类,是否public,abstract,final等等。
类索引、父亲索引与接口索引集合
类索引和父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据集合。类确定了这个类的全限定名,父亲索引确定这个父类的全限定名。不允许多继承,所以父类索引直邮一个。除了object都有父类。接口索引表示这个类实现了哪些接口。
字段表集合
字段表用于描述接口或类中声明的变量
方法表集合
访问标志、名称索引、描述符索引都表达清楚了,方法里面的代码经过编译器编译成字节码指令之后,存放在方法属性表集合中一个名为code的属性里面,属性表作为class文件格式最具扩展性的一种数据项目。
属性表集合
class文件、字段表、方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
class文件结构的发展
上面这些属性大部分都用于支持Java中许多新出现的语言特性,如枚举、变长参数、泛型、动态注解。
小结
class文件是Java虚拟机执行引擎的数据入口,也是技术体系的基础支柱之一。
说明
文中出现的图片,文字描述有些来自互联网,但是出处无法考究,如果侵犯您的相关权益,请联系我,核实后我会马上加上转载说明。谢谢!!!