《深入理解Java虚拟机》第6章 类文件结构

简单来说,Java代码-Java编译器-字节码(.class)-虚拟机执行,大概是这样一个过程。


6.3 Class类文件的结构
class文件是一组以8位字节为基础单位的二进制流。
class文件采用C 语言结构体的伪结构来存储
伪结构只有两种数据类型:无符号数和表。
无符号数可以描述数字、索引引用、数量值、或者按UTF-8编码构成字符串值。
表是由多个无符号数或其他表作为数据项构成的复合数据类型。
每个class文件的头4个字节被称为魔数,确定文件是否为能为虚拟机接受的class文件。因为扩展名是可以随意被改动的。
紧挨着的4个字节存的是class文件的版本号。

6.3.2 常量池
主次版本号之后是常量池。是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一。只有常量池的容量计数(u2类型数据)从1开始。常量池容量为十六进制0x0016,即十进制的22.则常量池有21个常量。
将0项空着是为了后面某些指向常量池的索引值的数据表达“不引用任何一个常量池项目”。
常量池主要存放两大常量:字面量(接近Java语言的常量概念)和符号引用(接近编译原理的概念)。

Java代码在进行Javac编译时,不像C有“连接”这一步,而是在虚拟机加载Class文件时进行动态链接。
当VM运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析并翻译到具体的内存地址之中。

常量池中每一项常量都是一个表,共有11种结构各不相同的表结构数据。

6.3.3 访问标志(acc_flags)
访问池结束后,紧接着的2个字节代表访问标志。用于识别一些类或接口层次的访问信息。包括:这个class是类还是接口,是否定义为public类型,是否定为abstract,final。

6.3.4 类索引、父类索引、接口索引集合
前两者是一个u2类型的数据,后者是一组u2类型的数据的集合。Class文件由着三项数据来确定这个类的继承关系。

6.3.5 字段表集合:描述接口或类中声明的变量。不包括方法内部的声明变量。
包括:字段作用域public 是类级变量还是实例级变量static,可变性final,并发可见性(volatile修饰符,是否强制从主内存读写),可否序列化(transient)

6.3.6 方法表集合
方法表结构:访问标志,名称索引,描述符索引,属性表集合。
与字段表集合对应,如果父类方法没有在子类中重写,方法表集合就不会出现来自父类的方法信息。

重载一个方法,除了要与原方法具有相同名称,还要求必须有一个与原方法不同的特征签名。特征签名是一个方法中各个参数在常量池中的字段符号引起的集合

6.3.7 属性表集合
不要求各个属性表具有严格的顺序,只要不与已有的属性名重复,任何人实现的编译器都可以向属性表写入自己定义的属性信息。
1.Code属性
Java程序的方法体内的代码经过编译,变为字节码存在Code指令中。

2.Exceptions属性
方法描述时在throws后列举的异常

3.LineNubmerTable
Java源码和字节码行号的关系

4.LocalVariableTable
栈帧中局部变量表的变量与Java源码中定义变量的关系
如果没有生成,其他人来引用方法,所有参数名会丢失

5.SourceFile
记录生成Class文件的源码文件名称

6.ConstantValue
通知虚拟机自动为静态变量赋值

7.InnerClasses
记录内部类和宿主类间的关系


6.4 Class文件结构的发展
对class文件格式的改进,主要在访问标志和属性表。用于支持Java中新出现的语言特性。
ACC_SYNTHETIC
ACC_BRIDGES
ACC_VARARGS
《深入理解Java虚拟机》第6章 类文件结构_第1张图片

你可能感兴趣的:(JVM)