class A {
A(int i) {System.out.println("A constructor"); }
}
class B {
B(int i) { System.out.println("B constructor"); }
}
public class C7 extends A {
B b = new B(1);
public C7(int i)
{
super(i); //@1
b = new B(i); //@2
System.out.println("C constructor");
}
public static void main(String[] args) {
C7 c = new C7(10);
}
}
输出为
A constructor
B constructor
B constructor
C constructor问题有两个1 在@1处 调用父类有参构造函数 为什么没输出A constructor
2 在@2处 有对象进行初始化,但是在构造体内。。从输出来看@2并没有在调用构造函数前完成初始化。为什么?
@2:类的初始化顺序为 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句
@2的话其实是先执行了外面的B b = new B(1);然后执行的里面的b = new B(i);这个顺序应该是初始化基类A,然后初始化C的成员变量,最后是完成C的构造函数里面的内容。
B b = new B(1); ----第二步,非静态成员的初始化在构造函数之前执行 public Main(int i)
{
super(i); //@1----第一步,先进行父类的构造函数调用,
b = new B(i); //@2----第三步,调用构造函数
System.out.println("C constructor");----第四步,
}
{
super(i); //@1 先打印出A constructor,不是因为这里有super(i)。
b = new B(i); //@2
System.out.println("C constructor");
} 如果你把super(i)去掉,那么C7的父类A必须提供一个无参数的默认构造函数,这时你会发现即使没有super(i),第一个打印出来的还是A constructor。那是因为初始化总是从root class开始逐级向下初始化。每个类在初始化的时候又是先静态变量,静态block,非静态变量,非静态block,再是构造函数。