Java中經常遇到的類執行順序

2021-08-25 06:10:55 字數 3215 閱讀 2409

下面是我寫的乙個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,...