JVM(五)类的初始化

265 阅读1分钟

类的初始化

类的初始化步骤

  • 假如类还未被加载和连接,那就先进行加载和连接
  • 假如类存在直接父类,并且这个父类还未被初始化,那就先初始化父类
  • 假如类中存在初始化语句,那就一次执行初始化语句

类的初始化时机

7种主动使用和被动使用,会触发类的初始化

当初始化类的时候,要求父类都已经被初始化,但是这条规则不适用于接口(interface)

  • 初始化一个类时,并不会先初始化它所实现的接口
public class Test06 {

    public static void main(String[] args) {
        //调用类的静态属性,观察接口是否被初始化,如果被初始化,那么就会输出`Thread Parent init`
        System.out.println(ThreadChild.a);
    }
}
interface ThreadParent {
    public static Thread thread = new Thread() {
        {
            System.out.println("Thread Parent init");
        }
    };
}

/**
 *
 */
class ThreadChild implements ThreadParent {
    public static int a = 2;
}

在这个例子中,可以明确看出,初始化一个类,并不会实例化他的接口

  • 在初始化一个接口时,并不会先初始化它的父接口
public class Test06 {

    public static void main(String[] args) {
        System.out.println(ThreadChild.childThread);
    }
}
interface ThreadParent {
    public static Thread thread = new Thread() {
        {
            System.out.println("Thread Parent init");
        }
    };
}

interface ThreadChild extends ThreadParent {
    public static final Thread childThread = new Thread(){
        {
            System.out.println("child thread initialized");
        }
    };
}

这个例子中,获取接口的静态属性,可以发现并没有触发父接口的初始化,但是会触发父接口的加载

只有当程序访问的静态变量或静态方法确实在当前类或当前接口中定义时,才可认为是对类或接口的主动使用

  • 调用ClassLoader的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化