下面是我寫的乙個demo:
package com.bw;
/** * @author brickworker * 關於類color的描述:測試單個類的執行順序問題 */
public classcolor
//靜態**塊
static
//非靜態**塊
//一般方法
void run()
public staticvoid main(string args)
}//執行結果:
//靜態**塊執行
//main方法執行
//非靜態**塊執行
//建構函式執行
//一般方法執行
真的覺得是對的麼?因為我們main的入口寫在了類本身之中。導致結果其實是不準確的。我們換個方式,信建立乙個rundemo來觸發執行:
package com.bw;
public class rundemo
}
//執行結果:
//main方法執行
//靜態**塊執行
//非靜態**塊執行
//建構函式執行
//一般方法執行
是吧,是不是main方法執行順序跑到最前面去了呢?前面一種情況是因為main方法放在了目標類中,如果要執行這個main方法,虛擬機會先初始化這個主類,所以會先執行static靜態**塊,關於這部分,以後我會寫一篇關於虛擬機器類載入機制的博文。總之,在看面試題的時候一定要看清楚main方法到底是放在**。
接下來,我們看看繼承的情況是如何的,以下是我寫的乙個繼承的demo,這裡要強調一點,有寫小夥伴為了看的更清楚,父類用system.err.println來列印,導致結果不同,兩種輸出方式是存在很大差別的,而且實驗一定要建立在公平公正的前提下:
//父類
package com.bw;
/** * * @author brickworker * 關於類father的描述:測試繼承執行順序父類 */
public classfather
//靜態**塊
static
//非靜態**塊
//一般方法
void run()
}//子類
package com.bw;
/** * * @author brickworker * 關於類son的描述:測試繼承執行順序子類 */
public classson extends father
//靜態**塊
static
//非靜態**塊
//子類重寫一般方法
@override
void run()
public staticvoid main(string args)
}//執行順序:
//父類靜態**塊執行
//子類靜態**塊
//main方法執行
//父類非靜態**塊執行
//父類建構函式執行
//子類非靜態**塊
//子類構造方法
//子類重寫一般方法執行
現在,我們把main方法單獨拿出來,和上面一樣,看看執行結果:
main方法執行
父類靜態**塊執行
子類靜態**塊
父類非靜態**塊執行
父類建構函式執行
子類非靜態**塊
子類構造方法
子類重寫一般方法執行
總結一下:標準的執行順序是:當前主程式》父類靜態**塊》子類靜態**塊》父類非靜態**塊》父類建構函式》子類非靜態**塊》子類構造方法》子類一般方法。那麼把上面的順序中關於父類執行的去掉,其實也符合我們前面討論的單個類執行順序。
其實在類載入機制中,類載入存在主動載入和被動載入(可以不用知道,對下面文章理解不妨礙,只是希望知其然更要知其所以然),在被動載入過程中很多並不會觸發初始化,所以在判斷被動引用的時候,執行順序會難很多,主要分為3中情況來具體說明:
一、通過子類呼叫了父類的靜態字段,子類不會被初始化
//父類
package com.bw;
/** * * @author brickworker * 關於類father的描述:測試繼承執行順序父類 */
public classfather
}//子類
package com.bw;
/** * * @author brickworker * 關於類son的描述:測試繼承執行順序子類 */
public classson extends father
}//測試類:
package com.bw;
public classrundemo
}//執行結果:
//main方法執行
//父類靜態**塊執行
//100
從上面可以看出,子類的靜態**都沒有執行,說明子類完全沒有初始化。
二、類作為陣列的元件型別不會觸發類初始化:
借用上面單類的color類:
package com.bw;
public classrundemo
}//執行結果:
//main方法執行
上面用color做為陣列的元件,沒有執行color的靜態方法,說明也沒有被初始化。
package com.bw;
/** * @author brickworker * 關於類color的描述:測試單個類的執行順序問題 */
public classcolor }//
package com.bw;
public classrundemo
}//執行結果:
//main方法執行
//red
從上面的結果可以看出,雖然呼叫了red,但是並有執行color的靜態**塊,說明它沒有被初始化。
三、常量池引用也會導致不初始化類
學習Python 中經常遇到疑惑的地方
可以這樣,不用儲存遞迴中的變數 import os deffindfile str dir os.path.abspath for x in os.listdir dir if os.path.isdir os.path.join dir,x findfile str,os.path.join di...
java類執行順序
如果父類有靜態成員賦值或者靜態初始化塊,執行靜態成員賦值和靜態初始化塊 如果類有靜態成員賦值或者靜態初始化塊,執行靜態成員賦值和靜態初始化塊 將類的成員賦予初值 原始型別的成員的值為規定值,例如int型為0,float型為0.0f,boolean型為false 物件型別的初始值為null 如果構造方...
java類執行順序
先執行父類的靜態變數和靜態 塊,如果有初值為其賦值,沒有就賦值預設初始值 執行當前類的靜態變數和靜態 塊,如果有初值為其賦值,沒有就賦值預設初始值 執行當前類成員的預設賦值,int 0,boolean false等 執行當前類的構造方法,顯示或者掩式呼叫父類的構造方法,如果構造方法 塊中有this,...