Java虚拟机 类初始化 阶段
Java虚拟机使用某个类的过程,可分为七个阶段:加载 - 验证 - 准备 - 解析 - 初始化 - 使用 - 卸载本文只介绍在什么情况下对类进行初始化。Java虚拟机规范对何时进行类的初始化做了严格规范,有且只有四种情况:1. 虚拟机启动时,指定的主类。 包含main方法的类。2. 遇到new、getstatic、putstatic、invokestatic四条
·
Java虚拟机使用某个类的过程,可分为七个阶段:
加载 - 验证 - 准备 - 解析 - 初始化 - 使用 - 卸载
本文只介绍在什么情况下对类进行初始化。
Java虚拟机规范对何时进行类的初始化做了严格规范,有且只有四种情况:
1. 虚拟机启动时,指定的主类。
包含main方法的类。
2. 遇到new、getstatic、putstatic、invokestatic四条指令时。
new:使用new关键字实例化对象。
getstatic:读引用一个类的静态字段。
putstatic:写引用一个类的静态字段。
invokestatic:调用一个类的静态方法。
3. 初始化一个类时,先初始化其父类。
接口则不是,只有真正引用到了父接口时,才会初始化。
4. 对类进行反射调用时。
测试代码:
MainClass:
package com.xuefeng.jvm.load;
/**
* 初始化类的时机
* 1. 虚拟机启动时指定的主类
* 2. new某类的对象时、引用某类的static变量时、设置某类的变量时、调用某类的static方法时
* 3. 初始化一个类时,先初始化其父类。接口则不是,真正使用到了父接口时,才会初始化父接口。
* 4. 通过反射调用某类时
* @author xuefeng
*
*/
public class MainClass {
static {
System.out.println("MainClass init.");
}
// 1
public static void main(String[] args) throws ClassNotFoundException {
// // 2
// System.out.println("SuperClass.F_V1 : " + SuperClass.F_V1);
// System.out.println("SuperClass.v1 : " + SuperClass.v1);
// // 3
// SubClass s1 = new SubClass();
// 3.1 如果通过子类名引用父类的static变量,是否会触发子类的初始化?
// 这取决于具体的虚拟机实现,Sun HotSpot虚拟机此时是不会触发子类的初始化的。
System.out.println(SubClass.v1);
// 4
Class.forName("com.xuefeng.jvm.load.SubClass");
}
}
SuperClass:
package com.xuefeng.jvm.load;
public class SuperClass {
static {
System.out.println("SuperClass init.");
}
/**
* 引用v1时,会初始化SuperClass
*/
public static int v1 = 1;
/**
* 引用F_V1时,不会初始化SuperClass
* static final的变量,已经在编译器放到了常量池里
*/
public static final int F_V1 = 1;
}
SubClass:
package com.xuefeng.jvm.load;
/**
*
* @author xuefeng
*
*/
public class SubClass extends SuperClass {
static {
System.out.println("SubClass init.");
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)