The constructor:
public Sandwich() {
System.out.println("Sandwich()");
}
Is translated by the compiler to:
public Sandwich() {
super(); // Compiler adds it if it is not explicitly added by programmer
// All the instance variable initialization is moved here by the compiler.
b = new Bread();
c = new Cheese();
l = new Lettuce();
System.out.println("Sandwich()");
}
So, the first statement in a constructor is the chaining of super class constructor. In fact, the first statement in any constructor chains to the super class constructor, for that matter. That is why first the super class constructor PortableLunch
is invoked, which again chains the call to it’s super class constructor, due to the super()
added by the compiler (remember?).
This chaining of constructor call is done till the class at the top of the inheritance hierarchy, thereby invoking the Object
class constructor at the end.
Now, after each the super class constructor has been executed, and all the super class fields have been initialized, the immediate subclass constructor start the execution after the super()
call. And then finally it comes back to the Sandwitch()
constructor, which now initializes your 3
fields.
So, basically your fields are initialized at last, and hence they are printed at the end, just before Sandwitch()
is printed.
Refer to JLS – ยง12.5 – Creation of New Class Instance for detailed explanation of the instance creation process.
As for your 2nd part of the question:
monitor.expect(new String[] {
"Meal()",
"Lunch()",
"PortableLunch()",
"Bread()",
"Cheese()",
"Lettuce()",
"Sandwich()"
});
This code is creating an unnamed array, and initializing it some string literals at the same time. It is similar to the way you would create a named array:
String[] arr = new String[] { "rohit", "jain" };