一、类加载的时机
- 场景遇到 new、getstatic、putstatic、invokestatic 四条字节码指令
- 使用new关键字实例化对象
- 读取/设置静态字段(除常量池内的静态字段)
- 调用静态方法
- 使用java.lang.reflect包对类型进行反射调用
- 初始化子类的时,发现未初始化父类
- 虚拟机启动时,初始化主类(main方法所在类)
- java.lang.invoke.MethodHandle最后解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial的方法句柄对应的类未初始化(JDK 7 动态语言)
- 使用default关键字的接口,实现类初始化时该接口未初始化(JDK 8)
二、类加载的过程
类的生命周期
加载
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
- 在方法区中生成一个代表这个类的 java.lang.Class 对象, 作为这个类的各种数据的访问入口
验证
确保 class 文件的字节流包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当成代码运行后不会危害虚拟机自身的安全;
- 文件格式验证
- 元数据验证
- 字节码验证
- 符号引用验证
准备
正式为类中定义的静态变量分配内存并设置零值;
注:JDK8 以前在永久代中分配内存,JDK8 以后在堆中分配内存
解析
- 类 || 接口解析
- 字段解析
- 方法解析
- 接口方法解析
初始化
标签:初始化,java,字节,JDK8,解析,过程,加载 From: https://www.cnblogs.com/Jcc-learningnotes/p/16667306.html