类加载的顺序

面试中经常问到的类初始化的顺序,现在给出个总结然后贴一段代码:

类初始化(注意先父类后子类)
1.类的静态变量、静态方法申明
2.静态变量进行赋值
3.静态代码块运行。
实例初始化(注意先父类后子类):
1.普通成员变量、方法申明
2.普通成员变量赋值
3.普通代码块运行
4.构造函数运行

Ps:如果在类的初始化过程中调用了实例化过程(如new了本类的对象)则会暂停加载类初始化转而先去加载实例化过程,结束以后再回归到类的初始化过程。

Ps:jvm虚拟机在初始化类的时候不会一边申明静态变量、静态方法一边给静态变量赋值,它只会先声明完所有的静态属性和方法,然后再按照代码顺序对静态属性进行赋值处理。而在这中间的过程(申明结束但是还没赋值的时候)所有的静态属性都为零值。

代码:

public class Test {

    public static int k = 0;

    public static Test t1 = new Test("t1");

    public static Test t2 = new Test("t2");

    public static int i  = print("i");

    public static int n = 99;

    public static int j = print("j");

    static {
        print("静态块");
    }

    {
        print("构造块");
    }



    public Test(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n;
        ++i;
    }


    public static int print(String str) {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n;
        return ++i;
    }

    public static void main(String[] args) {



    }

}

推荐阅读更多精彩内容