读《深入理解Java虚拟机》- 笔记06

《深入理解Java虚拟机:JVM高级特性与最佳实践》第2版

第7章 虚拟机类加载机制

复习:类的生命周期:加载、验证、准备、解析、初始化、使用、卸载

46. 加载

“加载”是“类加载”的发起阶段,要完成以下3件事:

(1)通过一个类的全限定名来获取定义此类的二进制字节流;

(2)将字节流代表的静态存储结构转换为方法区的运行时数据结构;

(3)在内存中生成一个代表这个类的 java.java.Class 对象,作为方法区这个类的各种数据的访问入口。(Class对象比较特殊,它保存在方法区而不是堆)

47. 验证

验证是连接阶段的第一步,目的是确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。大致完成4个检验动作:

(1)文件格式验证:保证输入的字节流能正确地解析并存储于方法区之内,针对 Class 文件规范

(2)元数据验证:对字节码描述的信息语义分析,保证符合 Java 语言规范要求,如这个类是否有父类(除 Object 外),是对数据类型的校验;

(3)字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的,是对类的方法体进行校验。

(4)符号引用验证:对类自身以外(常量池中的符号引用)的信息进行匹配性校验,如通过字符串描述的全限定名是否能找到相应的类,类、字段、方法的访问性是否可以被当前类访问。

验证是重要但非必要的阶段,可以用 -Xverify:none 参数关闭大部分的类验证措施,以缩短类加载的时间。

48. 准备

正式为类变量分配内存并设置类变量初始值,所使用的内存都将在方法区中进行分配。

注:分配初始值与初始化不同;final 修饰的类变量在准备阶段就赋值为目标值。

49. 解析

虚拟机将常量池内的符号引用替换为直接引用的过程。

符号引用:以一组符号来描述所引用的目标,能无歧义地定位到目标。可以是任何形式的字面量,定义在Class文件格式中;

直接引用:直接指向目标的指针、相对偏移量或是一个能间接定位到目标的句柄。符号引用翻译出来的直接引用因虚拟机不同可能不同。

50. 初始化

开始执行类中定义的Java程序代码(字节码),真正开始走代码逻辑(之前是虚拟机逻辑)。初始化是执行类构造器 () 方法的过程。

() 方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并产生的。收集顺序是由语句在源文件中出现的顺序决定的。静态语句块只能访问到定义在静态语句块之前的变量;定义在静态语句块之后的变量,在前面的静态语句块可以赋值,但是不能访问。

() 方法对于类或接口不是必需的,如果一个类中没有静态语句块,也没有对变量的赋值操作,那么可以不生成() 方法。

接口不能使用静态语句块,可以有变量初始化的复制操作,所以也会生成 () 方法。但与类不同的是执行接口的 () 方法不需要执行父接口的 () 方法。只有当父接口中定义的变量使用时,父接口才会初始化。接口的实现类在初始化时也不会执行接口的 () 方法。

这部分有很多“内幕”,值得好好看看,还挺有意思的。


未完待续...

读《深入理解Java虚拟机》- 笔记01

读《深入理解Java虚拟机》- 笔记02

读《深入理解Java虚拟机》- 笔记03

读《深入理解Java虚拟机》- 笔记04

读《深入理解Java虚拟机》- 笔记05

你可能感兴趣的:(读《深入理解Java虚拟机》- 笔记06)