构造函数:
public Sandwich() {
System.out.println("Sandwich()");
}
由编译器翻译为:
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()");
}
因此,构造函数中的第一个语句是超类构造函数的链接。事实上,任何构造函数中的第一个语句都链接到超类构造函数。这就是为什么首先是超类构造函数PortableLunch
被调用,这再次链接对其超类构造函数的调用,因为super()
由编译器添加(还记得吗?)。
构造函数调用的这种链接一直持续到继承层次结构顶部的类,从而调用Object
类构造函数在最后。
现在,在每个超类构造函数执行完毕,并且所有超类字段都已初始化后,直接子类构造函数在super()
称呼。最后又回到了Sandwitch()
构造函数,现在初始化你的3
字段。
所以,基本上你的字段最后被初始化,因此它们被打印在最后,就在之前Sandwitch()
被打印。
参考JLS - §12.5 - 创建新类实例 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5实例创建过程的详细说明。
至于你问题的第二部分:
monitor.expect(new String[] {
"Meal()",
"Lunch()",
"PortableLunch()",
"Bread()",
"Cheese()",
"Lettuce()",
"Sandwich()"
});
这段代码正在创建一个未命名数组,并同时初始化一些字符串文字。它类似于创建命名数组的方式:
String[] arr = new String[] { "rohit", "jain" };