Consider the code below
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();
}
}
Based on my understanding of class member initialization and order of constructor execution. I expected the output to be
Bread()
Cheese()
Lettuce()
Meal()
Lunch()
PortableLunch()
Sandwich()
as i believe the class members were initialized even before the main method was called. However I had the below output when i ran the program
Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()
my confusion is whey the Meal() Lunch() and PortableLunch() run before Bread() Cheese() and Lettuce() even though their constructors where called after.
解决方案
These are instance fields
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
They only exist (execute) if an instance is created.
The first thing that runs in your program is
public static void main(String[] args) {
new Sandwich();
}
Super constructors are called implicitly as the first thing in each constructor, ie. before 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()");}
}
After the super() calls, instance fields are instantiated again before the constructor code.
The order, reversed
new Sandwich(); // prints last
// the instance fields
super(); // new PortableLunch() prints third
super(); // new Lunch() prints second
super(); // new Meal(); prints first