fred-ye / summary

my blog
43 stars 9 forks source link

[Java]Java对象中各成员的初始化顺序 #35

Open fred-ye opened 9 years ago

fred-ye commented 9 years ago

今天在看书时,碰到了这么一个问题。有如下这么一段代码:

public class TestInitialize {
    public static void main(String args[]) {
        System.out.println(B.value);
    }   
}

class A {
    static int value = 100;
    static {
        System.out.println("A static block execute.");
    }   
}

class B extends A {
    static {
        System.out.println("B static block execute.");
    }
    public B() {
        System.out.println("B constructor execute.");
    }
}

本以为输出的结果中至少会有B static block execute.这么一段。后来执行后发现,结果如下:

A static block execute.
100

原来当访问一个java类或接口中的静态域时,只有真正声明这个域的类或接口才会被初始化。由于value是A类中的属性,B继承A。B.value直接访问的是类A中声明的静态域value。所以JVM只会初始化A.

既然看到这里,那就总结一下Java对象中各成员的初始化顺序。 1.父类静态成员和静态初始化块,按在代码中出现的顺序依次执行。 2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。 3.父类实例成员和实例初始化块,按在代码中出现的顺序依次执行。 4.执行父类的构造方法。 5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。 6.执行子类的构选方法。

代码验证

public class TestInitialize {
    public static void main(String args[]) {
        new B();
    }
}

class A {
    static int value = 100;
    /*
     * 注意,在初始化的过程中,静态代码块和静态域的出现顺序很重要,虚拟机会严格按照在源代码中的出现顺序来执行初始化操作。
     * 同样,对于成员变量和普通代码块也是一样的。
     */
    static {
        System.out.println("print static value in static block. static value:" + value);
        System.out.println("A static block1 execute.");
    }
    static {
        System.out.println("A static block2 execute.");
    }
    public int a;

    {
        System.out.println("A common block execute.");
    }

    public A() {
        System.out.println("A constructor execute.");
    }

}

class B extends A {
    static {
        System.out.println("B static block execute.");
    }

    {
        System.out.println("B common block execute.");
    }

    public B() {
        System.out.println("B constructor execute.");
    }
}

输出结果如下:

print static value in static block. static value:100
A static block1 execute.
A static block2 execute.
B static block execute.
A common block execute.
A constructor execute.
B common block execute.
B constructor execute.

代码很容易懂,这里就不解释了。