Java虚拟机 类初始化 阶段

来源:互联网 发布:javaweb程序员简历 编辑:程序博客网 时间:2024/05/20 02:26

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.");}// 1public 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);// 4Class.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.");}}


原创粉丝点击