繼承中的面試題,如下代碼:
父類:
class Fu {
static {
System.out.println("靜態代碼塊Fu");
}
{
System.out.println("構造代碼塊Fu");
}
public Fu() {
System.out.println("構造方法Fu");
}
}
子類:
class Zi extends Fu {
static {
System.out.println("靜態代碼塊Zi");
}
{
System.out.println("構造代碼塊Zi");
}
public Zi() {
System.out.println("構造方法Zi");
}
}
主函數:
class Test2_Extends {
public static void main(String[] args) {
Zi z = new Zi();
}
}
運行結果:
分析:
1、jvm調用了main方法,main進棧
2、遇到Zi z = new Zi();會先將Fu.class和Zi.class分別加載進內存,再創建對象,當Fu.class加載進內存
父類的靜態代碼塊會隨着Fu.class一起加載,當Zi.class加載進內存,子類的靜態代碼塊會隨着Zi.class一起加載
第一個輸出,靜態代碼塊Fu,第二個輸出靜態代碼塊Zi
3、走Zi類的構造方法,因爲java中是分層初始化的,先初始化父類,再初始化子類,所以先走的父類構造,但是在執行
父類構造時,發現父類有構造代碼塊,構造代碼塊是優先於構造方法執行的所以
第三個輸出構造代碼塊Fu,第四個輸出構造方法Fu
4、Fu類初始化結束,子類初始化,第五個輸出的是構造代碼塊Zi,構造方法Zi