天天看點

靜态變量、靜态構造函數、構造函數的初始化時機

今天C#課上,老師講到了關于靜态變量、靜态構造函數、構造函數的問題,感覺挺不錯的。在Java中也測試了一下,基本是一緻的,隻是形式有所不同。做個記錄,也給大家分享一波。

關于這三個概念的問題主要注意以下幾點:

一、初始化次序(依次是靜态變量、靜态構造函數、構造函數)

二、初始化次數(靜态的都隻會初始化一次)

三、初始化時機(對于靜态的隻要使用了類,就會初始化,非靜态的則要在建立對象的時候才初始化);

下面給出一個簡單的C#代碼來說明一下

class A
{
    public static int X;
    static A()
    {
        X = B.Y + 1;
    }
}

class B
{
    public static int Y = A.X + 1;
    static B(){}
}

public class Test
{
    public static void main(string[] args)
    {
        Console.Writeline("A.X = {0},B.Y = {1}",A.X,B.Y);   //輸出什麼内容?
    }
}
           

先簡單分析一下:(根據上面提到的注意事項可以很清楚的分析得到答案)

    因為在 Test 主類中最先使用了 A.X (根據初始化時機我們知道,此時,A類中所有靜态的成員都會初始化,但不會執行構造函數),又根據執行次序,是以先初始化靜态變量,因為沒有賦初值,是以預設 X 為 0,緊接着初始化 靜态構造函數,在靜态構造函數中,又使用了 B.Y(是以,跳到B類中執行靜态成員的初始化,靜态變量Y 在初始化時又一次使用了A.X,此時不是第一次使用是以不再初始化 X ,而是使用第一次初始化後的 X 的值,也就是預設值 0,是以 Y 的值為1。再初始化 B類 的靜态構造函數,這裡為空就沒有什麼處理了。B類靜态成員初始化結束後就回到了 A 類的靜态構造函數中,此時 B.Y 的值為1,是以 X 被重制指派為 2。)。然後再Test 類中又實用了B.Y,但因為不是第一次是以不再初始化,而是使用第一次初始化後的值 1 。

//是以輸出結果為:
A.X = 2,B.Y = 1
           

    在Java中,不存在靜态構造函數這一說法, 但是有靜态代碼塊,可以實作和靜态構造函數相似的功能。此外Java還有非靜态代碼塊(執行個體初始化塊)。是以在Java中就有:靜态變量、靜态代碼塊、非靜态代碼塊和構造函數。

    也是要注意上面提到的三個事項:

       初始化次序:靜态變量、靜态代碼塊、非靜态代碼塊、構造函數

       初始化次數:靜态變量和靜态代碼塊隻初始化一次,非靜态代碼塊和構造函數可初始化多次

       初始化時機:靜态變量和靜态代碼塊在使用類的時候就初始化、非靜态代碼塊和構造函數在建立對象時才初始化。

    對于具體例子,這裡就不提了。自己可以去測試各種情況下的代碼來檢驗,隻要根據這三個注意事項應該是都能分析出來的。

繼續閱讀