Java程序的运行时需要JVM支持的,而在JVM的运行过程中,需要把所有的Java类加载到虚拟机中才能运行。本文介绍了JVM的类加载机制。
类的生命周期与加载时机
类的生命周期
一个类从被加载到虚拟机内存中开始,到被卸载出内存为止,整个生命周期包括了 加载、验证、准备、解析、初始化、使用和卸载7个阶段。其中 验证、准备、解析 3部分统称为链接,如下图:
整个顺序并不是完全固定的,其中解析阶段可以在初始化之后再开始,这样便可以实现Java的运行时绑定(动态绑定)机制。
类的加载时机
JVM虚拟机规范并没有对类的加载时机做出严格的要求,只规定了以下五种情况需要立刻触发类的初始化:
其余条件下,可以由JVM虚拟机自行决定何时去加载一个类。
- 遇到new,getstatic,putstatic和invokestatic这四个字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
- 使用反射机制对类进行调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
- 当初始化一个类时,如果其父类还没有进行过初始化,则需要先触发其父类的初始化。
- 虚拟机启动时,用户需要指定一个要执行的主类(包含main方法),此时会先初始化这个类
- 使用JDK1.7的动态语言支持时,如果一个
MethodHandle
实例最后的解析结果包含REF_getStatic
,REF_putStatic
,REF_invokeStatic
的方法句柄,且这个方法句柄对应的类没有初始化,则需要先对其进行初始化。
主动引用和被动引用
上面五种条件也被称为对类的主动引用,除此之外其他引用类的方式都不会触发初始化,即类的被动引用,举个例子: