class Test1 {
void f(){
System.out.println("Test1.f()");
}
Test1(){
System.out.println("Test1() before f()");
f();
System.out.println("Test1() after f()");
}
}class Test2 extends Test1 {
private int a = 1;

Test2(int a){
this.a = a;
System.out.println("Test2.Test2().a = " + a);
}

void f(){
System.out.println("Test2.f().a = " + a);

}
}public class Test {
public static void main(String[] args){
new Test2(5);
}
}
输出结果是:Test1() before f()
Test2.f().a = 0
Test1() after f()
Test2.Test2().a = 5
大家能帮忙解释一下这个初始化的顺序吗?在调用父类构造器时,存在一个多态,程序运行到f()时,是不是还没有编译子类的成员变量 private int a = 1???

解决方案 »

  1.   

    没有显式的调用super,就会调用父类的默认构造函数。调用顺序是:父类构造函数-->子类构造函数(先执行private int a = 1;然后在执行子类构造函数内的语句)。
    所以在父类的构造函数内部调用f()方法时,因为实际类型是Test2,调用的是子类的f()方法,a的值为0。等到执行子类构造函数时,a已经是1了。
      

  2.   

    然后你Test2的构造函数里System.out.println("Test2.Test2().a = " + a);输出的是传入参数a,传入5,所以输出5.
      

  3.   

    在每一级构造函数初始化之前,先给成员变量赋默认值,之后上溯父类,一直到Object,然后再往下执行,到每一级时,给成员变量显示赋值,再执行构造函数的语句。一直到最后那个子类。
    楼主的 程序,在父类执行f()时,因为多态的特性,实际执行的是子类的f(),这时子类里的 a=0(默认值)。
      

  4.   

    子类都会先调用父类的构造
    因为有着依赖
    无参的就直接调
    有参要用super显示调用
      

  5.   

    没有显式的调用super,就会调用父类的默认构造函数