這方面知識一直沒有整理,但大家經常討論類的靜態變數、成員變數、靜態初始化塊、非靜態初始化塊、構造器,及繼承父類時,它們的初始化順序都是怎樣的,所以找了個機會認真整理一下,幫助大家脫坑:
首先介紹一下這幾個傢伙,捋清它們是幹嘛的:
靜態變數 / 成員變數:是類的屬性,靜態變數屬於類,被static修飾,成員變數屬於物件例項。
靜態成員方法 / 普通成員方法:靜態成員方法屬於類所有,類例項化前即可使用,普通成員方法可以訪問類中的任何成員,靜態成員方法只能訪問類中的靜態成員。
靜態初始化塊 / 非靜態初始化塊:初始化塊是類的成員之一,每次類的建立會隱式的呼叫它。本質上是乙個**塊,或方法體。靜態的被static修飾。
構造器:用於例項化物件,分為有參無參。
這些都是類的基本結構。下面通過**示例分析它們的執行順序:
public
class
datetest
}class
demo1
static
}
第一次輸出:
第二次輸出:
兩次比較後我們就可以知道:
普通初始化塊:建立物件時隱式呼叫
靜態初始化塊:類載入時隱式呼叫
由這個例子我們又知道:
靜態初始化塊只在類載入時呼叫一次,而普通初始化塊隨著建立物件而執行。
public
class
datetest
}class
demo3
string a=
msg(
"普通屬性1");
public
static string msg
(string info)
static
static string b=
msg(
"靜態屬性1");
string c=
msg(
"普通屬性2");
static string d=
msg(
"靜態屬性2");
由本例可知:在乙個類中如果有多個不同的初始化塊,初始化屬性,構造器,
執行順序是:靜態初始化塊|靜態變數 > 普通初始化塊|普通變數 > 構造器
public
class
datetest
}class
demo3
string a=
msg(
"普通屬性1");
public
static string msg
(string info)
static
static string b=
msg(
"靜態屬性1");
string c=
msg(
"普通屬性2");
static string d=
msg(
"靜態屬性2");
本例比較有特色,產生了巢狀,即在某個靜態初始化塊中new了新物件,我們發現,一開始先執行靜態初始化塊,沒問題,但後面並沒有執行下一層的靜態初始化塊,而執行的普通屬性和普通初始化塊,這是由於如果一直優先執行靜態初始化塊的話會產生死迴圈,此時虛擬機器將執行靜態塊的權利只賦予最先進行例項化的類,這樣就能防止死迴圈的產生。
一看就懂的SwitchHosts
switchhosts 是乙個管理 切換多個 hosts 方案的工具。它是乙個免費開源軟體。日常開發工作中,我們可能經常需要切換各種 hosts 繫結,比如在本地開發時可能需要乙個開發環境的 hosts 繫結方案,發布到測試環境後又有乙個測試環境的 hosts 繫結方案,然後可能還有乙個預發布環境,...
一看就懂的氣泡排序
不用走啦,看得懂的啦!相鄰兩個數比較大小,較大的下沉 較小的上浮。從第乙個數開始,比較第乙個數和第二個數大小,如果第乙個數比第二個數大,則交換兩個數的位置,使大的數排在後面,依次比較第二個數和第三個數,使第三個數比第二和第乙個數大,直到倒數兩個數,將最大的數移動到最後一位。演算法分為兩個迴圈 1.外...
一看就懂的記憶體對齊
記憶體對齊對於程式設計師來說透明的,這是編譯器該做的事,將每個資料按排到合適的位置,這也是編譯器優化的結果。所以了解記憶體對齊的原理對於乙個程式設計師寫 是十分必要的,就不會導致大量的記憶體碎片產生。1 對於結構體的第乙個成員,將它在整個結構體在記憶體中分布的偏移量看成0,以後的每乙個資料成員的偏移...