深入理解jvm-类加载

本文为读书笔记,个人觉得相比垃圾回收,这一部分是十分重要的,故做个留存笔记

1.类的生命周期

加载->验证->准备->解析->初始化->使用->卸载
深入理解jvm-类加载
要点:

  • 加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的
  • 解析阶段在某些情况下可以在初始化阶段之后再开始
  • 类加载过程的第一个阶段“加载”的实际没有明确定义
  • 但六种情况必须立即对类进行“初始化” :
    1.遇到new、getstatic、putstatic或invokestatic这四条字节码指令时, 如果类型没有进行过初始化,则需要先触发其初始化阶段。

这四条指令触发条件为:·

  • 使用new关键字实例化对象的时候。
  • 读取或设置一个类型的静态字段·
  • 调用类的静态方法时

2.反射调用,若没有初始化则初始化
3. main方法的执行主类
4.反射方法句柄解析为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial对应的类没有进行过初始化
5.被default关键字修饰的接口方法被实现的类先初始化
6.初始化类时,父类未初始化则触发父类的初始化
有且只有这六种场景表示对一个类型的主动引用
实现案例:

  • 通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。
  • 常量会在编译的时候加入到类的常量池内,本质上没有直接引用到定义常量的类,因此不会触发初始化
  • 数组不会触发类的初始化,原因为这个类型虚拟机自动生成的、直接继承于java.lang.Object的子类,创建动作由字节码指令newarray触发。
    在考虑一个类是否被初始化的时候,考虑一下它是不是被动引用了;即类初始化是懒惰的
    这里还有资料测试了,我把它列出来,不会引发初始化的
  • 类对象.class
  • 类加载的loadClass方法
  • Class.forname()第二个参数为false的时候
  • 接口也有初始化过程,差不多与类一致

2.类加载的过程

晚安,明天再看