在繼承中代碼的執行順序爲:1.父類靜態對象和靜態代碼塊 2.子類靜態對象和靜態代碼塊函數
3.父類非靜態對象和非靜態代碼塊 4.父類構造函數spa
5.子類非靜態對象和非靜態代碼塊 6.子類構造函數code
1.對於本題來講:在只想new Sub(5)的時候,父類先初始化了 int flag = 1,而後執行父類的構造函數Super(),父類構造函數中執行的test()方法,因子類是重寫了test()方法的,所以父類構造函數中的test()方法實際執行的是子類的test()方法,因此輸出爲Sub.test() flag=1,接着執行子類構造函數Sub(5) 將flag賦值爲5,所以輸出結果Sub.Sub() flag=5。最終選擇了A:Sub.test() flag=1 Sub.Sub() flag=5對象
public class Demo {
class Super {
int flag=1; ①父類非靜態對象 Super(){ ②父類構造函數 test(); ③子類是重寫了test()方法的,所以父類構造函數中的test()方法實際執行的是子類的test()方法 }
void test(){ System.out.println("Super.test() flag="+flag); } }
class Sub extends Super { Sub(int i){ ④子類構造函數
flag=i; System.out.println("Sub.Sub()flag="+flag); }
void test(){ ③ System.out.println("Sub.test()flag="+flag); } }
public static void main(String[] args) {
new Demo().new Sub(5); } }
2.初始化類的時候,首先在其餘任何事物發生以前,將分配給對象的存儲空間初始化爲二進制的0。因此加載時,對t1初始化爲null,對static靜態塊作了初步的初始化,可是還未執行裏面的代碼。而後按照靜態變量的初始化順序,首先對t1進行具體的初始化,因爲static靜態塊已經進行了初步的初始化,因此這時候是直接跳過這裏的,因此首先輸出 blockA,而後初始化t1後,執行到static靜態塊以後,再執行裏面的內容,因此輸出blockB,最後執行普通的初始化塊blockA. blockAblockBblockAblog
類中靜態塊按照聲明順序執行,而且(1)和(2)不須要調用new類實例的時候就執行了(意思就是在類加載到方法區的時候執行的)繼承
執行順序優先級:靜態塊>main()>構造塊>構造方法
class
public class Test { public static Test t1 = new Test(); ① { System.out.println("blockA"); } static { System.out.println("blockB"); ② } public static void main(String[] args) { Test t2 = new Test(); ③ } }