今天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中就有:靜态變量、靜态代碼塊、非靜态代碼塊和構造函數。
也是要注意上面提到的三個事項:
初始化次序:靜态變量、靜态代碼塊、非靜态代碼塊、構造函數
初始化次數:靜态變量和靜态代碼塊隻初始化一次,非靜态代碼塊和構造函數可初始化多次
初始化時機:靜态變量和靜态代碼塊在使用類的時候就初始化、非靜态代碼塊和構造函數在建立對象時才初始化。
對于具體例子,這裡就不提了。自己可以去測試各種情況下的代碼來檢驗,隻要根據這三個注意事項應該是都能分析出來的。