一、背景:
在面試中,在java基礎方面,類的加載順序經常被問及,很多時候我們是搞不清楚到底類的加載順序是怎么樣的,那么今天我們就來看看帶有繼承的類的加載順序到底是怎么一回事?在此記下也方便以后復習鞏固!
二、測試步驟:
1.父類代碼
1 package com.hafiz.zhang; 2 3 public class Fu 4 { 5 private int i = print("this is father common variable"); 6 private static int j = print("this is father static variable"); 7 static{ 8 System.out.println("this is father static code block"); 9 } 10 { 11 System.out.println("this is father common code block"); 12 } 13 public Fu(){ 14 System.out.println("this is father constructor"); 15 } 16 17 static int print(String str){ 18 System.out.println(str); 19 return 2; 20 } 21 }
2.子類代碼
1 package com.hafiz.zhang; 2 3 public class Zi extends Fu 4 { 5 private int l = print("this is son common variable"); 6 private static int m = print("this is son stati variable"); 7 static{ 8 System.out.println("this is son static code block"); 9 } 10 { 11 System.out.println("this is son common code block"); 12 } 13 public Zi(){ 14 System.out.println("this is son constructor"); 15 } 16 public static void main(String[] args) { 17 new Zi(); 18 } 19 }
最后運行結果為:
下面讓我們修改一下兩個類中靜態代碼塊和靜態成員變量的位置並重新運行
3.修改后的父類代碼
1 package com.hafiz.zhang; 2 3 public class Fu 4 { 5 static{ 6 System.out.println("this is father static code block"); 7 } 8 { 9 System.out.println("this is father common code block"); 10 } 11 public Fu(){ 12 System.out.println("this is father constructor"); 13 } 14 15 static int print(String str){ 16 System.out.println(str); 17 return 2; 18 } 19 private int i = print("this is father common variable"); 20 private static int j = print("this is father static variable"); 21 }
4.修改后的子類代碼
1 package com.hafiz.zhang; 2 3 public class Zi extends Fu 4 { 5 static{ 6 System.out.println("this is son static code block"); 7 } 8 { 9 System.out.println("this is son common code block"); 10 } 11 public Zi(){ 12 System.out.println("this is son constructor"); 13 } 14 public static void main(String[] args) { 15 new Zi(); 16 } 17 private int l = print("this is son common variable"); 18 private static int m = print("this is son stati variable"); 19 }
修改后的運行結果:
三、測試結果
由測試結果可知:程序首先加載類,然后再對類進行初始化。
加載類的順序為:先加載基類,基類加載完畢后再加載子類。
初始化的順序為:先初始化基類,基類初始化完畢后再初始化子類。
最后得出類加載順序為:先按照聲明順序初始化基類靜態變量和靜態代碼塊,接着按照聲明順序初始化子類靜態變量和靜態代碼塊,而后按照聲明順序初始化基類普通變量和普通代碼塊,然后執行基類構造函數,接着按照聲明順序初始化子類普通變量和普通代碼塊,最后執行子類構造函數。
對於本測試中的執行順序為:先初始化static的變量,在執行main()方法之前就需要進行加載。再執行main方法,如果new一個對象,則先對這個對象類的基本成員變量進行初始化(非方法),包括構造代碼塊,這兩種是按照編寫順序按序執行的,再調用構造函數。 關於繼承的初始化機制,首先執行含有main方法的類,觀察到Zi類含有基類Fu,即先加載Fu類的static變量,再加載Zi類的static變量。加載完static變量之后,調用main()方法,new Zi()則先初始化基類的基本變量和構造代碼塊,再調用基類的構造方法。然后再初始化子類Zi的基本變量和構造代碼塊,再執行子類的構造函數。