首先上图
接下来,逐个介绍各个过程:
1.加载
(1)通过一个类的全限定名来获取这个类的二进制字节流。
(2)将这个字节流所代表的的静态存储结构转化为运行时数据结构。
(3)在内存中(HotSpot虚拟机中是方法区)生成代表这个类的java.lang.Class对象,作为这个类的访问入口。
2.验证
这一过程的目的是确保二进制字节流包含的信息符合虚拟机的要求,并且不会危害虚拟机的安全。
3.准备
为类变量(静态变量)分配内存并设置初始值。
4.解析
将常量池中的符号引用替换为直接引用的过程。
5.初始化
执行类构造器<clinit>方法的过程。
有且只有5种情况立即对类进行初始化:
(1)遇到new、getstatic、putstatic、invokestatic字节码时。
如下情况会遇到这些字节码:
- 使用new关键字实例化对象
- 读取或设置一个类的静态变量
- 调用一个类的静态方法
(2)对类进行反射调用时。
(3)初始化子类时,如果该子类的父类还没初始化,应先将其父类进行初始化。
(4)虚拟机启动时,会初始化主类(包含main方法的类)。
(5)当使用jdk1.7动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getstatic,REF_putstatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行初始化,则需要先出触发其初始化。