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并没有在调用构造函数前完成初始化。为什么?

解决方案 »

  1.   

    @1:第一个输出结果就是
    @2:类的初始化顺序为 子类构造函数 -> 父类构造函数 -> 实例化成员变量 -> 继续执行子类构造函数的语句
      

  2.   

    @1不是调用了父类A的有参构造函数吗。
    @2的话其实是先执行了外面的B b = new B(1);然后执行的里面的b = new B(i);这个顺序应该是初始化基类A,然后初始化C的成员变量,最后是完成C的构造函数里面的内容。
      

  3.   


     B b = new B(1); ----第二步,非静态成员的初始化在构造函数之前执行  public Main(int i)   
      {   
      super(i); //@1----第一步,先进行父类的构造函数调用,
      b = new B(i); //@2----第三步,调用构造函数
      System.out.println("C constructor");----第四步,
      }   
      

  4.   

    如果子类构造函数中显示调用了父类指定的构造函数,那么初始化父类时使用的构造函数就是这个指定的构造函数,否则使用父类默认的构造函数。  public C7(int i)   
      {   
      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,再是构造函数。