类的生命周期
类的生命周期包括如下7个阶段:
加载的理解
所谓加载,简而言之就是将Java类的字节码文件加载到机器内存中,并在内存中构建出Java类的原型--类模板对象。
类模板对象--其实就是在Java类在JVM内存中的一个快照,JVM将从字节码文件中解析出的常量池,类字段,类方法等信息存储到类模板中,这样JVM在运行期便能通过类模板而获取Java类中的任意信息,能够对Java类的成员变量进行遍历,也能进行Java方法的调用
加载完成的操作
加载阶段,简而言之,查找并加载类的二进制数据,生成Class的实例。
验证阶段
当类加载到系统后,就开始链接操作,验证是链接操作的一部分
- 目的是保证加载的字节码是合法的、合理并符合规范的
大体上Java虚拟机需要做以下检查:
- 其中格式验证会和加载阶段一起执行。验证通过之后,类加载器才会成功将类的二进制数据信息加载到方法区中
- 格式验证之外的验证操作将会在方法区中进行
准备阶段
简而言之,就是为类的静态变量分配内存,并将其初始化为默认值
- 注意:
- 这里不包含基本数据类型的字段用static final修饰的情况,因为final在编译的时候就会分配了,准备阶段会显式赋值
解析阶段
简而言之,将类,接口,字段和方法的符号引用转为直接引用
在HotSpot VM中,加载,验证,准备和初始化会按照顺序有条不紊的执行,但链接阶段中的解析操作往往会伴随着JVM在执行完初始化之后再执行
初始化阶段
> 简而言之,就是为类的静态变量赋予正确的初始值
> 执行类构造器<clinit>()方法的过程
> 当初始化一个类的时候,如果发现其父类还没进行初始化,则需要先触发器父类的初始化
> 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步。
使用 static + final 修饰,且显式赋值中不涉及到方法或构造器调用的基本数据类型或String类型的显式赋值,是在准备阶段进行赋值
什么时候会发生类初始化?
- 类的主动引用(一定会发生类的初始化)
- 当虚拟机启动,先初始化main方法所在的类
- new一个类的对象
- 调用类的静态成员和静态方法
- 使用java.lang.reflect包的方法对类进行反射调用
- 当初始化一个类,如果其父类没有被初始化,则会先初始化它的父类
- 类的被动引用
- 当访问一个静态域时,只有真正声明这个域的类才会被初始化。如:当通过子类引用父类的静态变量,不会导致子类初始化
- 通过数组定义类引用,不会触发此类的初始化
- 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)

浙公网安备 33010602011771号