本题出自《Think in Java》第8章,主要考验在存在继承关系时的类加载顺序,挑战一下吧~
class Bread {
static { System.out.println("load class: Bread"); }
Bread() { System.out.println("Bread()"); }
}
class Cheese {
static { System.out.println("load class: Cheese");}
Cheese() { System.out.println("Cheese()"); }
}
class Lettuce {
static { System.out.println("load class: Lettuce"); }
Lettuce() { System.out.println("Lettuce()"); }
}
class Meal {
static { System.out.println("load class: Meal"); }
Meal() { System.out.println("Meal()"); }
}
class Lunch extends Meal {
static { System.out.println("load class: Lunch"); }
Lunch() {
System.out.println("Lunch() 1");
make();
System.out.println("Lunch() 2");
}
public void make() {
System.out.println("make lunch");
}
}
class PortableLunch extends Lunch {
static { System.out.println("load class: PortableLunch"); }
PortableLunch() { System.out.println("PortableLunch()"); }
}
public class Sandwich extends PortableLunch {
private int minutes = 5;
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
static { System.out.println("load class: Sandwich"); }
Sandwich() {
System.out.println("Sandwich()");
}
public void make() {
System.out.println("make sandwith with:" + b + "," + c + "," + l);
System.out.println("need " + minutes + " minutes.");
}
public static void main(String[] args) {
new Sandwich();
}
}
(答案在最后,先别着急看,做完再对答案才有意思)
如果没有思路的话,可以参考几个要点:
1. 存在继承关系时,类加载顺序为“由父至子”;
2. 当进行实例化时,子类的实例化动作会导致其父类的先完成实例化动作;
3. 按照声明顺序调用成员的初始化方法。
具体到这个例子:
1. 当调用Sandwich
的main
方法时,看到其由父类,而且父类还有父类,因此会寻根溯源找到最祖宗辈儿Meal
,依次由父类到子类完成类加载;
2. Sandwich
的main
方法中要实例化一个Sandwich
对象,也是本着“长辈优先”的原则,依次进行实例化,想想很对嘛,没有老子哪来的儿子;
3. Lunch
的构造方法中调用make
方法,由于多态的原因,会调用Sandwich
的make
方法,而此时Sandwich
的成员变量尚未完成初始化,所以都是默认值(0或null);
4. 实例化时,该类的成员变量按照代码顺序依次初始化。
又到了对答案的时间:
load class: Meal
load class: Lunch
load class: PortableLunch
load class: Sandwich
Meal()
Lunch() 1
make sandwith with:null,null,null
need 0 minutes.
Lunch() 2
PortableLunch()
load class: Bread
Bread()
load class: Cheese
Cheese()
load class: Lettuce
Lettuce()
Sandwich()
你做对了吗?