search.png
关于我
menu.png
Java review(7) 成员初始化顺序

口说无凭,还是看测试:

    @Test
    public void test1() throws Exception {
        E e = new E();
    }

E中B、C是普通成员,D是静态成员,P是父类型,P中Pc是普通成员,Pd是静态成员



class B {
    B() {
        System.out.println("init B");
    }
}
class C {
    C() {
        System.out.println("init C");
    }
}
class D {
    D() {
        System.out.println("init static D");
    }
}
class Pc {
    Pc() {
        System.out.println("init parent Pc");
    }
}
class Pd {
    Pd() {
        System.out.println("init parent static Pd");
    }
}
class P {
    private Pc pc = new Pc();

    private static Pd pd = new Pd();

    P() {
        System.out.println("init parent P");
    }
}
class E extends P {

    private int i;

    private B b = new B();

    private C c = new C();

    private static D d = new D();

    E() {
        System.out.println("construction E");
        i = 123;
    }
}

输出结果是:

init parent static Pd
init static D
init parent Pc
init parent P
init B
init C
construction E

因此初始化顺序是

父类型静态成员->子类静态成员->父类型成员->父类型构造器->子类型成员->子类型构造器
(同是成员变量或者同是静态成员则按照代码中的顺序进行初始化)

为什么静态变量最先初始化?

因为静态变量在类第一次被调用时就会立即初始化。而对象实例化时才初始化成员变量、调用构造器。

以下例子可以验证:

    @Test
    public void test3() throws Exception {
        F.noUse();
    }
class F {
    private static D d = new D();

    private static int i;

    private float f;

    static {
        System.out.println("init static i");
        i = 233;
    }

    {
        System.out.println("init f");
        f = 123;
    }

    static void noUse(){}
}

结果:

init static D
init static i

这里并没有实例化F,只是调用了其静态方法。

那么可以猜测是在类加载时,就进行了静态域的初始化了吗?

    @Test
    public void test2() throws Exception {
        Class<E> eClass = (Class<E>) this.getClass().getClassLoader().loadClass("cn.hengyumo.review.r1.E");
    }

输出结果为空,这意味着并不是在类加载时,进行的静态域的初始化

最后一个疑问,在域中进行初始化会比直接初始化提前执行吗?

以下测试证明:不是的,域的初始化和直接初始化还是按照代码顺序进行执行。

class E extends P {

    private int i;

    private B b2;

    {
        System.out.println("b2:");
        b2 = new B();
    }

    private B b = new B();
    private B b3;

    {
        System.out.println("b3:");
        b3 = new B();
    }

    private C c = new C();

    private static D d2;

    static {
        System.out.println("d2:");
        d2 = new D();
    }

    private static D d = new D();

    private static D d3;

    static {
        System.out.println("d3:");
        d3 = new D();
    }

    E() {
        System.out.println("construction E");
        i = 123;
    }
}

结果:

init parent static Pd
d2:
init static D
init static D
d3:
init static D
init parent Pc
init parent P
b2:
init B
init B
b3:
init B
init C
construction E

版权声明

知识共享许可协议 本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
发布时间:2019年11月28日 14:54:02

评论区#

还没有评论哦,期待您的评论!

关闭特效