由单例模式学到:静态构造函数和静态字段
編譯器在編譯的時候,會事先分析所需要的靜態字段,如果這些靜態字段所在的類有靜態的構造函數,則忽略靜態字段的初始化,否則先進行靜態字段的初始化。對類的靜態成員初始化的順序取決于在Main函數中的引用順序,先引用到的先進行初始化,但如果類的靜態成員的初始化依賴于其它類的靜態成員,則會先初始化被依賴類的靜態成員。而帶有靜態構造函數的類的靜態字段,只有在引用到的時候才進行初始化。
接下來,用實例來對以上的一段總結性的描述逐句分析:
1、編譯器在編譯的時候,會事先分析所需要的靜態字段,如果這些靜態字段所在的類有靜態的構造函數,則忽略靜態字段的初始化,否則先進行靜態字段的初始化。
==無靜態構造函數:上圖中實例的執行流程就是紅色數字標記的順序,首先,在編譯器進行編譯時,發現Main主函數中會用到A類的靜態字段X,所以,會在程序開始執行之前去對能用到的靜態字段進行初始化(在無靜態構造函數的前提下);B類中的靜態字段沒有初始化的原因是編譯時沒有發現用到此靜態字段;靜態字段在IL中標記為BeforeFliedInit;
將上圖中的普通構造函數換為靜態構造函數會是什么效果呢?
==靜態構造函數:當類A中有靜態的構造函數時,其靜態字段不再提前去初始化,而是當調用時才進行初始化;當執行完靜態字段后,會緊接著去執行靜態構造函數中的代碼塊;值得一說的是,如果A類中有一個靜態的方法,當Main函數調用時則先執行A類的靜態構造函數,再去執行靜態方法;
?
2、對類的靜態成員初始化的順序取決于在Main函數中的引用順序,先引用到的先進行初始化(這個就不用寫例子了,對于兩個相同狀態的類(都含有靜態構造函數或都沒有),其中類靜態字段的初始化的順序都是按照其在Main函數中調用時的順序執行的),當然如果過一個有靜態構造函數,另一個沒有靜態的構造函數的話,那就另當別論了!
3、如果類的靜態成員的初始化依賴于其它類的靜態成員,則會先初始化被依賴類的靜態成員。
==首先,上圖的代碼中A類和B類都含有普通的構造函數,并且主程序中都用到了這兩個類中的靜態字段,那么它們的靜態字段就會在主程序運行之前進行初始化,然后當有多個靜態字段時,他們的執行順序就是按照主程序中調用的順序來執行!如上圖:先初始化Y,再初始化X
4、如果類的靜態成員的初始化依賴于其它類的靜態成員,則會先初始化被依賴類的靜態成員
==如上圖,在編譯器編譯時,檢測到會用到A類的靜態字段,那么就會在Main主函數運行之前對A類的X字段進行初始化,但是X字段中又用到了B類的Y字段,所以就會先初始化B類中的Y字段,再初始化A類的X字段!也就是先初始化被依賴的靜態字段。
?5、而帶有靜態構造函數的類的靜態字段,只有在引用到的時候才進行初始化。
這里才是博客中主要的,靜態構造函數的作用就是不讓靜態字段在主程序運行之前進行初始化,而是當主程序調用它時才執行,并且緊接著執行該字段索在類的靜態構造函數中的代碼
==上例中因為A類和B類都含有靜態的構造函數,所有就避免了其類中靜態字段的提前初始化,當調用用時才執行,并且在上例中A類的X字段又依賴B類的Y字段(因為都是普通的構造函數,所以不會提前執行,而是用到時才執行),所以當程序到達A的X字段時就會去調用B類的Y字段(緊接著執行B類的靜態構造函數),回來之后再繼續執行A類的靜態夠走啊函數!
這個博客中寫得也非常的詳細:博客地址網址
?
2013-9-22更新
==當第一次調用靜態字段時,就會執行所有靜態字段,并執行靜態構造函數,下次再調用其他靜態字段時,就直接取即可,不必在執行一遍User類
==只要使用此類,例如實例化,就會執行類中的靜態字段。
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的由单例模式学到:静态构造函数和静态字段的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python学习入门基础教程(learn
- 下一篇: cakephp对数据库的增删改查