一、概念
类加载:虚拟机把类的数据从Class文件加载到内存中,并对数据进行校验,转化解析,和初始化,最终形成可以被虚拟机直接使用的Java类型。
二、加载时机
1.加载
加载阶段虚拟机完成的工作为:
1)通过类全限定名来获取定义此类的二进制流。
2)将字节流代表的静态存储结构转化为方法区运行时的数据结构。
3)在内存中生成代表这个类的java.lang.class对象,作为这个类的访问入口。
2.验证
确保Class文件中包含的数据符合当前虚拟机的要求。
1)文件格式
2)元数据
3)字节码
4)符号引用
3. 准备
为类变量分配内存,并设置类变量初始值。(非final变量初始值为0, final变量为所附的值)
4. 解析
虚拟机将常量池内符号引用替换为直接引用的过程
5. 初始化
初始化阶段是类加载最后一步。
初始化阶段执行<clinit>()方法。(该方法是由编译器自动收集所有类变量的赋值动作和静态语句块合并产生的)
初始化阶段并不会调用父类的<clinit>()方法(虚拟机会保证父类的初始化方法会在子类之前执行)
五种必须对类进行初始化的情况
1)遇到new、getstatic、putstatic和invokestatic这四条指令时候。
2)使用java.lang.reflect包的方法对类进行反射调用时候
3)初始化一个类的时候需要初始化父类
4)虚拟机启动时加载的主类
5)使用JDK1.7,如果一个java.lang.invoke.MehodHandle在实例最后的解析结果REF_getstatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个句柄对应的类没有进行过初始化,则需要先触发初始化。