日期:2014-05-20  浏览次数:20927 次

一个JAVA问题,我迷惑了。。。。
关于JAVA的初始化顺序问题:
Java code

public class Element {
    Element(String o){
        System.err.println("==>"+o);
    }
}


Java code

public class Test1 {
    {
        System.out.println("3");
    }

    // 4.父类构造器
    Test1() {
        System.out.println("4");
    }

    // 1.父类静态初始化块
    static {
        System.out.println("1");
    }
    public Element e=new Element("SupB");
    public static Element es=new Element("StaticSupA");
}


Java code

public class Test2 extends Test1 {
    Test2() {
        System.out.println("6");
    }

    // 2.子类静态初始化块
    static {
        System.out.println("2");
    }
    // 5.初始化块
    {
        System.out.println("5");
    }
    public Element e=new Element("SubB");
    public static Element es=new Element("StaticSubA");

    public static void main(String[] args) {
        // 即使newTest2实例,静态块初始化也进行
        System.gc();
        new Test2();
    }
}



我一直以为运行结果是:

1
==>StaticSupA
2
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
==================
上面的结果确实出来了,但是再运行,它又会是:

1
2
==>StaticSupA
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
==================
还会是这个:
1
==>StaticSupA
==>StaticSubA
2
3
==>SupB
==>SubB
4
5
6
=====================
这个怎么解释,难道是:先静态,后非静态。至于静态和非静态的初始化顺序,那是不确定的?或者说是随机的?

------解决方案--------------------
确实随机。。。不懂帮顶 mark一下
------解决方案--------------------
分组:
第一组:1;==>StaticSupA; 2; ==>StaticSubA.
第二组:剩下的

规则1:
第一组(初始化时执行) > 第二组(创建对象时执行)
表现为:静态初始化块 > 普通初始化块
静态初始化块 > 构造方法
静态变量 > 构造方法

规则2:普通初始化块不依赖构造方法
表现为:普通初始化块和构造方法无先后顺序

注意,规则2出自本人推断,鉴于初始化过程没必要考虑语法逻辑

自行思考 仅供参考




------解决方案--------------------
丢一条:
静态变量 > 普通初始化块
------解决方案--------------------
1
==>StaticSupA
2
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
这个顺序比较符合常规解释!至于其它结果 可能是线程时间片影响的

期待大牛解释!mark...

------解决方案--------------------
如果将 System.gc();语句注释掉的话,就会一直呈现如下打印信息
// System.gc(); // 至于加上这条就会出现你的那种情况,俺也不明白为什么,望高人解答
1
==>StaticSupA
2
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
------解决方案--------------------
public class Element {
Element(String o){
System.err.println("==>"+o);
}
}
貌似是会受Element中的System.err.println的影响,如果也改成System.out.println,你加上System.gc()与不加上结果都是一样,而且结果都是符合我们正常理解逻辑的,输出结果:
父类静态代码块static{}...
父类静态类属性static Element...
子类静态块static{}...
子类静态类属性static Element...
父类代码块{}...
父类类属性Element....
父类构造方法Test1()...
子类代码块{}...
子类类属性Element...
子类构造方法Test()...

对System.err.println(),疑惑ing...
------解决方案--------------------
探讨

public class Element {