最詳細類初始化的順序,一看就懂

2021-09-24 04:45:27 字數 2201 閱讀 3089

這方面知識一直沒有整理,但大家經常討論類的靜態變數、成員變數、靜態初始化塊、非靜態初始化塊、構造器,及繼承父類時,它們的初始化順序都是怎樣的,所以找了個機會認真整理一下,幫助大家脫坑:

首先介紹一下這幾個傢伙,捋清它們是幹嘛的:

靜態變數 / 成員變數:是類的屬性,靜態變數屬於類,被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,以後的每乙個資料成員的偏移...