九又四分之三站台

0%

类的加载时机

类的生命周期:

  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载

其中加载验证准备初始化和卸载这5个阶段的顺序是确定的

类初始化的条件

虚拟机规范规定了有且只有5种情况必须立即对类进行初始化

  1. 遇到new, getstatic,putstatic或者invokestatic这4条字节码指令时,如果类还没有初始化,则需要先触发其初始化。生成这4条指令最常见的代码场景是: 使用new关键字实例化对象, 读取或设置一个类的静态字段(被final修饰,已经在编译期把结果放入常量池的静态字段除外),调用一个类的静态方法。
  2. 使用java.lang.reflect包对类进行反射调用的时候,如果类还没有进行过初始化则需要进行初始化
  3. 当初始化一个类的时候,如果其父类还没有初始化
  4. 当虚拟机启动的时候,用户需要指定一个要执行的类(包含main()方法的那个类),虚拟机会先初始化这个主类
  5. 当使用jdk1.7的动态语言支持时,如果有MethodHandle实例最后解析结果REF_getStatic,REF_putStatic,REF_invokeStatic的句柄对应的类没有初始化

这5中场景的行为成为对一个类进行主动引用,除此之外所有引用类的被动引用方式都不会触发初始化

被动引用

  1. 通过子类引用父类的静态字段,子类不会初始化
  2. 通过数组来定义引用类
1
Springp[] spring = new Spring[10];//不会触发Spring类的初始化
  1. 调用被final修饰的静态字段 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用定义常量的类,因此不会触发初始化