編譯器在編譯的時候,會事先分析所須要的靜態字段,若是這些靜態字段所在的類有靜態的構造函數,則忽略靜態字段的初始化,不然先進行靜態字段的初始化。對類的靜態成員初始化的順序取決於在Main函數中的引用順序,先引用到的先進行初始化,但若是類的靜態成員的初始化依賴於其它類的靜態成員,則會先初始化被依賴類的靜態成員。而帶有靜態構造函數的類的靜態字段,只有在引用到的時候才進行初始化。html
接下來,用實例來對以上的一段總結性的描述逐句分析:函數
一、編譯器在編譯的時候,會事先分析所須要的靜態字段,若是這些靜態字段所在的類有靜態的構造函數,則忽略靜態字段的初始化,不然先進行靜態字段的初始化。
spa
==無靜態構造函數:上圖中實例的執行流程就是紅色數字標記的順序,首先,在編譯器進行編譯時,發現Main主函數中會用到A類的靜態字段X,因此,會在程序開始執行以前去對能用到的靜態字段進行初始化(在無靜態構造函數的前提下);B類中的靜態字段沒有初始化的緣由是編譯時沒有發現用到此靜態字段;靜態字段在IL中標記爲BeforeFliedInit;htm
將上圖中的普通構造函數換爲靜態構造函數會是什麼效果呢?
blog
==靜態構造函數:當類A中有靜態的構造函數時,其靜態字段再也不提早去初始化,而是當調用時才進行初始化;當執行完靜態字段後,會緊接着去執行靜態構造函數中的代碼塊;值得一說的是,若是A類中有一個靜態的方法,當Main函數調用時則先執行A類的靜態構造函數,再去執行靜態方法;get
二、對類的靜態成員初始化的順序取決於在Main函數中的引用順序,先引用到的先進行初始化(這個就不用寫例子了,對於兩個相同狀態的類(都含有靜態構造函數或都沒有),其中類靜態字段的初始化的順序都是按照其在Main函數中調用時的順序執行的),固然若是過一個有靜態構造函數,另外一個沒有靜態的構造函數的話,那就另當別論了!編譯器
三、若是類的靜態成員的初始化依賴於其它類的靜態成員,則會先初始化被依賴類的靜態成員。
博客
==首先,上圖的代碼中A類和B類都含有普通的構造函數,而且主程序中都用到了這兩個類中的靜態字段,那麼它們的靜態字段就會在主程序運行以前進行初始化,而後當有多個靜態字段時,他們的執行順序就是按照主程序中調用的順序來執行!如上圖:先初始化Y,再初始化Xit
四、若是類的靜態成員的初始化依賴於其它類的靜態成員,則會先初始化被依賴類的靜態成員
編譯
==如上圖,在編譯器編譯時,檢測到會用到A類的靜態字段,那麼就會在Main主函數運行以前對A類的X字段進行初始化,可是X字段中又用到了B類的Y字段,因此就會先初始化B類中的Y字段,再初始化A類的X字段!也就是先初始化被依賴的靜態字段。
五、而帶有靜態構造函數的類的靜態字段,只有在引用到的時候才進行初始化。
這裏纔是博客中主要的,靜態構造函數的做用就是不讓靜態字段在主程序運行以前進行初始化,而是當主程序調用它時才執行,而且緊接着執行該字段索在類的靜態構造函數中的代碼
==上例中由於A類和B類都含有靜態的構造函數,全部就避免了其類中靜態字段的提早初始化,當調用用時才執行,而且在上例中A類的X字段又依賴B類的Y字段(由於都是普通的構造函數,因此不會提早執行,而是用到時才執行),因此當程序到達A的X字段時就會去調用B類的Y字段(緊接着執行B類的靜態構造函數),回來以後再繼續執行A類的靜態夠走啊函數!
這個博客中寫得也很是的詳細:博客地址網址
2013-9-22更新
==當第一次調用靜態字段時,就會執行全部靜態字段,並執行靜態構造函數,下次再調用其餘靜態字段時,就直接取便可,沒必要在執行一遍User類
==只要使用此類,例如實例化,就會執行類中的靜態字段。