首先看下這段測試代碼
public class ClassLoader {
public static void main(String[] args) {
// 3.第四步,new一個類,但在new之前要處理匿名代碼塊
new ClassLoader();
}
// 1.第二步,靜態變量和靜態代碼塊的加載順序由編寫先後決定
static int sNum = 4;
// 2.第三步,靜態塊,然後執行靜態代碼塊,因爲有輸出,故打印
static {
System.out.println("靜態方法塊執行 a");
}
// 4.第五步,按照順序加載匿名代碼塊,代碼塊中有打印
{
System.out.println("靜態變量 =" + sNum);
sNum += 3;
System.out.println("類方法快執行 b");
System.out.println("靜態變量 =" + sNum);
}
// 5.第六步,按照順序加載變量
int mNum = 5;
// 6.第七步,按照順序打印
{
System.out.println("成員方法塊執行");
}
// 7.第八步,最後加載構造函數,完成對象的建立
ClassLoader() {
System.out.println("成員變量 =" + mNum);
System.out.println("構造器執行 d");
}
// 8.靜態方法,調用的時候才加載
static void run()
{
System.out.println("static function");
}
// 8.內部類,調用的時候才加載
static class Interior {
static {
System.out.println("Interior");
}
}
}
看下輸出結果
輸出結果表明,程序的執行順序爲:
如果類還沒有被加載:
1、先執行父類的靜態代碼塊和靜態變量初始化,並且靜態代碼塊和靜態變量的執行順序只跟代碼中出現的順序有關。
2、執行子類的靜態代碼塊和靜態變量初始化。
3、執行父類的實例變量初始化
4、執行父類的構造函數
5、執行子類的實例變量初始化
6、執行子類的構造函數
如果類已經被加載:
則靜態代碼塊和靜態變量就不用重複執行,再創建類對象時,只執行與實例相關的變量初始化和構造方法。