在《JAVA编程思想》(第四版)的94页提到:“无法阻止自动初始化的进行,它将在构造器被调用之前发生。”
public class MySuper {
protected String str = "out of Construction, in the super class.";
MySuper(){
System.out.println(str);
str = "in the Construction, in the super class.";
System.out.println(str);
}
public static void main(String[] args){
MySuper mySuper = new MySuper();
}
}
也就是说,在实例化一个MySuper对象时,会首先将str初始化为"out of Construction, in the super class.",然后才会进入构造器主体执行。
上面的程序运行结果为:
out of Construction, in the super class.
in the Construction, in the super class.
但是在该书的159页上提到:存在继承关系的时候,构造器的调用顺序如下:
“1,调用基类构造器;2,按声明顺序调用成员的初始化方法;3,调用导出类构造器的主体。”
这里我有一个疑惑:不管程序员有没有在子类构造器首句写上super(),编译器都会在那里加上,即子类构造器首句一定是super(X,X)。那么,按照159页上的说法,我个人认为流程是这样的,1,调用子类的构造器;2,执行super();3,执行声明的初始化语句;4,执行子类构造器余下的语句。
但是,这样就和94页上说的,“声明语句先于构造器执行”矛盾。(我应该理解有问题。)
不过,我另外用一种方法验证了一下
public class MyChild extends MySuper{
private String subStr = "out of Construction, in the child class.";
MyChild(){
System.out.println("in child "+str);
System.out.println(subStr);
subStr = "in Construction, in the child class.";
System.out.println(subStr);
}
public static void main(String[] args){
MyChild myChild = new MyChild();
}
}
执行结果如下:
out of Construction, in the super class.
in the Construction, in the super class.
in child in the Construction, in the super class.
out of Construction, in the child class.
in Construction, in the child class.
基本和书上说的一致,就是还是无法判断super()和声明初始化的顺序,不过这也没有关系,仔细想想,其实子类声明初始化的语句肯定不会和超类的任何数据成员有关系(不管是什么访问权限)。
不过调用顺序这个问题最终还是没有明白,哪位大牛明白,敬请赐教。