Create two classes, A and B, with default constructors (empty argument lists) that announce themselves. Inherit a new class called C from A, and create a member of class B inside C. Do not create a constructor for C. Create an object of class C and observe the resluts.
class A { A(){ println("A() " + this);} }
class B extends A { B(){ System.out.println("B() " + this);} }
class D extends A {
B b1 = new B();
D(){ System.out.println("D() " + this);}
}
class C extends A {
D d = new D();
public static void main(String[] args) {
C c = new C(); // will construct an A first
}
} /* Output:
A() C@a90653
A() D@1fb8ee3
A() B@61de33
B() B@61de33
D() D@1fb8ee3
*///:~
这个例子可以看出,程序的执行顺序:
I. 调用C的构造器,输出“A() C@a90653 ”;
II. 调用D的构造器,输出“A() D@1fb8ee3 ”(为什么不是接着就输出“D() D@1fb8ee3 ”呢?);
III. 创建B对象实例b1,调用B的构造器,输出:“A() B@61de33 B() B@61de33”
IV. 输出“D() D@1fb8ee3 ”
想来想去,觉得上面的解释不对。在initiailization中讲到:“在类的内部,定义变量的先后顺序决定了初始化的顺序。即变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。”所以应该这么解释:
首先,初始化C,调用其基类构造器,输出“A() C@a90653 ”;然后,初始化变量d,仍旧先调用其基类构造器,输出“A() D@1fb8ee3”;接着,初始化D中的变量b1,于是先调用其基类构造器,输出“A() B@61de33”,然后调用B本身的构造器B(),输出“B() B@61de33 ”;再接着,调用D本身的构造器D(),输出“D() D@1fb8ee3”;最后,调用C本身构造器C()(这里没有显示定义C的构造器,所以没有任何输出)
但是,为什么基类的构造器会在每个子类初始化的第一步执行呢?
于是在网上找了个构造器执行顺序:
I. 父类的静态成员赋值和静态块
II. 子类的静态成员和静态块
III. 父类的构造方法
IV. 父类的成员赋值和初始化块
V. 父类的构造方法中的其它语句
VI. 子类的成员赋值和初始化块
VII. 子类的构造方法中的其它语句
为了理解的更清晰些,在Javaeye上找到了个例子,只要看完这个例子就明白了:
1) 单个类中的静态变量、变量以及构造函数的初始化顺序
public class SingleInitialOrder
{
public static String staticField = "静态变量";
public String field = "变量";
static
{
System.out.println(staticField);
System.out.println("静态初始化块");
}
{
System.out.println(field);
System.out.println("初始化块");
}
public SingleInitialOrder()
{
System.out.println("构造器");
}
public static void main(String[] args)
{
new SingleInitialOrder();
}
}/* Output:
静态变量
静态初始化块
变量
初始化块
构造器
*///:~
2) 子类和父类中静态变量、变量以及构造函数的初始化顺序
public class ParentChildInitialOrder extends Parent
{
public static String s_StaticField = "子类--静态变量";
public String s_Field = "子类--变量";
static
{
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
public ParentChildInitialOrder()
{
System.out.println("子类--构造器");
}
public static void main(String[] args)
{
new ParentChildInitialOrder();
}
}
class Parent
{
public static String p_StaticField = "父类--静态变量";
public String p_Field = "父类--变量";
static
{
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
public Parent()
{
System.out.println("父类--构造器");
}
} /* Output:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
*///:~