关于JAVA的初始化顺序问题:public class Element {
Element(String o){
System.err.println("==>"+o);
}
}
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");
}
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
=====================
这个怎么解释,难道是:先静态,后非静态。至于静态和非静态的初始化顺序,那是不确定的?或者说是随机的?
Element(String o){
System.err.println("==>"+o);
}
}
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");
}
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
=====================
这个怎么解释,难道是:先静态,后非静态。至于静态和非静态的初始化顺序,那是不确定的?或者说是随机的?
第一组:1;==>StaticSupA; 2; ==>StaticSubA.
第二组:剩下的规则1:
第一组(初始化时执行) > 第二组(创建对象时执行)
表现为:静态初始化块 > 普通初始化块
静态初始化块 > 构造方法
静态变量 > 构造方法规则2:普通初始化块不依赖构造方法
表现为:普通初始化块和构造方法无先后顺序注意,规则2出自本人推断,鉴于初始化过程没必要考虑语法逻辑自行思考 仅供参考
==>StaticSupA
2
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
这个顺序比较符合常规解释!至于其它结果 可能是线程时间片影响的期待大牛解释!...
// System.gc(); // 至于加上这条就会出现你的那种情况,俺也不明白为什么,望高人解答
1
==>StaticSupA
2
==>StaticSubA
3
==>SupB
4
5
==>SubB
6
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...
果然是err的问题我都没发现用的是err害得我一直担心。。不过为何用err会出现随机的输出还要等待大牛
另外,其实println本身也不是一个线程安全的方法,也就是不能保证输出先后顺序跟执行顺序绝对一致,不过因为本案例中只有主线程这1个所以倒也没这方面的问题。
我刚说第一组(初始化时执行) > 第二组
先说初始化部分,请问你怎么保证父类静态代码块static{}...早于子类静态块static{}...
你也不能保证父类静态类属性static Element..早于子类静态类属性static Element...
这两点都没办法确定下面第二组(初始化部分)
我刚才也说了不确定"普通初始化块和构造方法无先后顺序"
但在本例中LZ用输出流来表达顺序,那只能说在本例中"普通初始化块和构造方法无先后顺序"成立了
所以强烈质疑这个顺序
父类代码块{}...
父类类属性Element....
父类构造方法Test1()...
子类代码块{}...
子类类属性Element...
子类构造方法Test()...