Java构造函数-继承层次结构中的执行顺序


问题内容

考虑下面的代码

  class Meal {
    Meal() { System.out.println("Meal()"); }
  }

  class Bread {
    Bread() { System.out.println("Bread()"); }
  }

  class Cheese {
    Cheese() { System.out.println("Cheese()"); }
  }

  class Lettuce {
    Lettuce() { System.out.println("Lettuce()"); }
  }

  class Lunch extends Meal {
    Lunch() { System.out.println("Lunch()"); }
  }

  class PortableLunch extends Lunch {
    PortableLunch() { System.out.println("PortableLunch()");}
  }

  class Sandwich extends PortableLunch {
    private Bread b = new Bread();
    private Cheese c = new Cheese();
    private Lettuce l = new Lettuce();
    public Sandwich() {
      System.out.println("Sandwich()");
    }
    public static void main(String[] args) {
      new Sandwich();
    }
  }

基于我对类成员初始化和构造函数执行顺序的理解。我期望输出是

Bread()
Cheese()
Lettuce()
Meal()
Lunch()
PortableLunch()    
Sandwich()

因为我相信类成员甚至在调用main方法之前就已初始化。但是当我运行程序时,我得到以下输出

Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()

我的困惑是,尽管Meal()Lunch()和PortableLunch()在Bread()Cheese()和Lettuce()之前运行,即使它们的构造函数被调用。


问题答案:

这些是实例字段

private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();

它们仅在创建实例时存在(执行)。

在程序中运行的第一件事是

public static void main(String[] args) {
     new Sandwich();
}

超级构造函数被隐式地称为每个构造函数中的第一件事。之前System.out.println

class Meal {
    Meal() { System.out.println("Meal()"); }
}

class Lunch extends Meal {
    Lunch() { System.out.println("Lunch()"); }
}

class PortableLunch extends Lunch {
    PortableLunch() { System.out.println("PortableLunch()");}
}

在以后super()的调用,实例字段在构造函数代码之前再次实例化。

顺序相反

new Sandwich(); // prints last
// the instance fields
super(); // new PortableLunch() prints third
super(); // new Lunch() prints second
super(); // new Meal(); prints first