美文网首页
Java虚拟机-类文件结构

Java虚拟机-类文件结构

作者: 慎独静思 | 来源:发表于2022-08-29 23:19 被阅读0次

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符。
Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数
无符号数属于基本的数据类型,以u1,u2,u4,u8来分别代表1个字节,2个字节,4个字节和8个字节的无符号数,无符号数可以用来描述数字,索引引用,数量值或者按照UTF-8编码构成字符串值。
是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性的以_info结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。
每个Class文件的头4个字节称为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。魔数为0xCAFEBABE。
紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号,第7和第8个字节是主版本号。高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。
紧接着主次版本号之后的是常量池入口,常量池可以理解为Class文件之中的资源仓库,它是一个表类型的数据项目。常量池中主要存放两大类常量:字面量和符号引用,字面量比较接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值等。符号引用包括三类常量:类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。
在常量池结束之后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息。
类索引,父类索引和接口索引集合都按顺序排列在访问标志之后,类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名,接口索引集合描述这个类实现了哪些接口,这三项数据确定了这个类的继承关系。
字段表用于描述接口或者类中声明的变量。字段包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量。
方法表和字段表的描述方式类似,方法表用来描述方法。方法里的Java代码,经过编译器编译成字节码指令后,存放在方法属性表集合中一个名为”Code“的属性里面。
属性表 在Class文件,字段表,方法表都可以携带自己的属性表集合,以用于描述某些场景专有的信息。
在任何实例方法里面,都可以通过this关键字访问到此方法所属的对象,这个实现其实非常简单,通过javac编译器编译的时候把对this关键字的访问转变为对一个普通方法参数的访问,然后在虚拟机调用实例方法时自动传入此参数而已。
异常表是Java代码的一部分,编译器使用异常表而不是简单的跳转命令来实现Java异常及finally处理机制。
Exceptions属性的作用是列举出方法中可能抛出的受查异常。
LineNumberTable属性用于描述Java源码行号与字节码行号之间的对应关系。
LocalVariableTable属性用于描述栈帧中局部变量表中的变量与Java源码中定义的变量之间的关系。
SourceFile属性用于记录生成这个Class文件的源码文件名称。
InnerClasses属性用于记录内部类与宿主类之间的关联。
Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(操作数)而构成。
加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。
Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步,这两种同步结构都是使用管程来支持的。Java虚拟机的指令集中有monitorenter和monitorexit两条指令来支持synchronized关键字的语义。

相关文章

网友评论

      本文标题:Java虚拟机-类文件结构

      本文链接:https://www.haomeiwen.com/subject/pysqnrtx.html