深入理解java虚拟机第六章笔记

第六章 类文件结构

一 Class类文件结构

Class文件是一组以8位字节为基础单位的二进制流。文件格式采用一种类似C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表

无符号数属于基本数据类型,主要可以用来描述数字、索引符号、数量值或者按照UTF-8编码构成的字符串值,大小使用u1、u2、u4、u8分别表示1字节、2字节、4字节和8字节。

表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有的表都习惯以“_info”结尾。那么表是干嘛的呢?表主要用于描述有层次关系的复合结构的数据,比如方法、字段。需要注意的是class文件是没有分隔符的,所以每个的二进制数据类型都是严格定义的。

1. 魔数与Class文件的版本

每个Class文件的头四个字节被称为魔数,唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。

紧接着魔数的四个字节是Class文件的版本号。5,6字节是次版本号,7,8字节是主版本号。

2. 常量池

紧接着主版本号的是常量池入口,常量池可以理解为Class文件之中的资源仓库,这种数据类型是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的项目之一。

常量池中主要存放两大类常量:字面量和符号引用。字面量比较接近于java语言层面的常量概念,如文本字符串、声明为final的常量值等。而符号引用则属于编译原理方面的概念,包括:类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。

读取常量池的时候首先读取标志位,判断常量类型,就可以知道对应的结构,获取对应的信息了。

3. 访问标志

在常量池后紧接着的2个字节代表访问标志,这个标志用于识别一些类或者接口层次的信息,包括:这个Class是类还是接口;是否定义为public类型;是否为abstract类型;如果是类,是否被声明为final等。

4. 类索引,父类索引与接口索引集合

这个数据项主要用于确定这个类的继承关系。其中类索引和父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。在Java中由于不允许多继承,所以父类索引是唯一的,但是一个类可以实现多个接口,所以得到的接口索引是一个集合,表示这个类实现了哪些接口

5. 字段表集合

字段表用于描述接口或者类中声明的变量。字段包括类级变量以及实例级变量,但不包括局部变量。自然,描述一个字段的信息包括:字段的作用域(public、protected、private)、实例变量与否(static)、可变性(final)、并发可见性(volatile)、可否被序列化(transient)、字段数据类型(基本数据类型、对象、数组)、字段名称。

6. 方法表集合

JVM中对方法表的描述与字段表是一致的,包括了:访问标志、名称索引、描述符索引、属性表集合。方法表的结构与字段表是一致的,区别在于访问标志的不同.在方法中不能用volatile和transient关键字修饰,所以这两个标志不能用在方法表中。在方法中添加了字段不能使用的访问标志,比如方法可以使用synchronized、native、strictfp、abstract关键字修饰,所以在方法表中就增加了相应的访问标志。

7. 属性表集合

java7中预定义了21项属性,对于每个属性的结构,没有特别严格的要求,并且可以自定义属性信息,jvm运行时会忽略不认识的属性。

你可能感兴趣的:(java并发编程)