由单例模式学到:静态构造函数和静态字段
編譯器在編譯的時(shí)候,會(huì)事先分析所需要的靜態(tài)字段,如果這些靜態(tài)字段所在的類(lèi)有靜態(tài)的構(gòu)造函數(shù),則忽略靜態(tài)字段的初始化,否則先進(jìn)行靜態(tài)字段的初始化。對(duì)類(lèi)的靜態(tài)成員初始化的順序取決于在Main函數(shù)中的引用順序,先引用到的先進(jìn)行初始化,但如果類(lèi)的靜態(tài)成員的初始化依賴(lài)于其它類(lèi)的靜態(tài)成員,則會(huì)先初始化被依賴(lài)類(lèi)的靜態(tài)成員。而帶有靜態(tài)構(gòu)造函數(shù)的類(lèi)的靜態(tài)字段,只有在引用到的時(shí)候才進(jìn)行初始化。
接下來(lái),用實(shí)例來(lái)對(duì)以上的一段總結(jié)性的描述逐句分析:
1、編譯器在編譯的時(shí)候,會(huì)事先分析所需要的靜態(tài)字段,如果這些靜態(tài)字段所在的類(lèi)有靜態(tài)的構(gòu)造函數(shù),則忽略靜態(tài)字段的初始化,否則先進(jìn)行靜態(tài)字段的初始化。
==無(wú)靜態(tài)構(gòu)造函數(shù):上圖中實(shí)例的執(zhí)行流程就是紅色數(shù)字標(biāo)記的順序,首先,在編譯器進(jìn)行編譯時(shí),發(fā)現(xiàn)Main主函數(shù)中會(huì)用到A類(lèi)的靜態(tài)字段X,所以,會(huì)在程序開(kāi)始執(zhí)行之前去對(duì)能用到的靜態(tài)字段進(jìn)行初始化(在無(wú)靜態(tài)構(gòu)造函數(shù)的前提下);B類(lèi)中的靜態(tài)字段沒(méi)有初始化的原因是編譯時(shí)沒(méi)有發(fā)現(xiàn)用到此靜態(tài)字段;靜態(tài)字段在IL中標(biāo)記為BeforeFliedInit;
將上圖中的普通構(gòu)造函數(shù)換為靜態(tài)構(gòu)造函數(shù)會(huì)是什么效果呢?
==靜態(tài)構(gòu)造函數(shù):當(dāng)類(lèi)A中有靜態(tài)的構(gòu)造函數(shù)時(shí),其靜態(tài)字段不再提前去初始化,而是當(dāng)調(diào)用時(shí)才進(jìn)行初始化;當(dāng)執(zhí)行完靜態(tài)字段后,會(huì)緊接著去執(zhí)行靜態(tài)構(gòu)造函數(shù)中的代碼塊;值得一說(shuō)的是,如果A類(lèi)中有一個(gè)靜態(tài)的方法,當(dāng)Main函數(shù)調(diào)用時(shí)則先執(zhí)行A類(lèi)的靜態(tài)構(gòu)造函數(shù),再去執(zhí)行靜態(tài)方法;
?
2、對(duì)類(lèi)的靜態(tài)成員初始化的順序取決于在Main函數(shù)中的引用順序,先引用到的先進(jìn)行初始化(這個(gè)就不用寫(xiě)例子了,對(duì)于兩個(gè)相同狀態(tài)的類(lèi)(都含有靜態(tài)構(gòu)造函數(shù)或都沒(méi)有),其中類(lèi)靜態(tài)字段的初始化的順序都是按照其在Main函數(shù)中調(diào)用時(shí)的順序執(zhí)行的),當(dāng)然如果過(guò)一個(gè)有靜態(tài)構(gòu)造函數(shù),另一個(gè)沒(méi)有靜態(tài)的構(gòu)造函數(shù)的話(huà),那就另當(dāng)別論了!
3、如果類(lèi)的靜態(tài)成員的初始化依賴(lài)于其它類(lèi)的靜態(tài)成員,則會(huì)先初始化被依賴(lài)類(lèi)的靜態(tài)成員。
==首先,上圖的代碼中A類(lèi)和B類(lèi)都含有普通的構(gòu)造函數(shù),并且主程序中都用到了這兩個(gè)類(lèi)中的靜態(tài)字段,那么它們的靜態(tài)字段就會(huì)在主程序運(yùn)行之前進(jìn)行初始化,然后當(dāng)有多個(gè)靜態(tài)字段時(shí),他們的執(zhí)行順序就是按照主程序中調(diào)用的順序來(lái)執(zhí)行!如上圖:先初始化Y,再初始化X
4、如果類(lèi)的靜態(tài)成員的初始化依賴(lài)于其它類(lèi)的靜態(tài)成員,則會(huì)先初始化被依賴(lài)類(lèi)的靜態(tài)成員
==如上圖,在編譯器編譯時(shí),檢測(cè)到會(huì)用到A類(lèi)的靜態(tài)字段,那么就會(huì)在Main主函數(shù)運(yùn)行之前對(duì)A類(lèi)的X字段進(jìn)行初始化,但是X字段中又用到了B類(lèi)的Y字段,所以就會(huì)先初始化B類(lèi)中的Y字段,再初始化A類(lèi)的X字段!也就是先初始化被依賴(lài)的靜態(tài)字段。
?5、而帶有靜態(tài)構(gòu)造函數(shù)的類(lèi)的靜態(tài)字段,只有在引用到的時(shí)候才進(jìn)行初始化。
這里才是博客中主要的,靜態(tài)構(gòu)造函數(shù)的作用就是不讓靜態(tài)字段在主程序運(yùn)行之前進(jìn)行初始化,而是當(dāng)主程序調(diào)用它時(shí)才執(zhí)行,并且緊接著執(zhí)行該字段索在類(lèi)的靜態(tài)構(gòu)造函數(shù)中的代碼
==上例中因?yàn)锳類(lèi)和B類(lèi)都含有靜態(tài)的構(gòu)造函數(shù),所有就避免了其類(lèi)中靜態(tài)字段的提前初始化,當(dāng)調(diào)用用時(shí)才執(zhí)行,并且在上例中A類(lèi)的X字段又依賴(lài)B類(lèi)的Y字段(因?yàn)槎际瞧胀ǖ臉?gòu)造函數(shù),所以不會(huì)提前執(zhí)行,而是用到時(shí)才執(zhí)行),所以當(dāng)程序到達(dá)A的X字段時(shí)就會(huì)去調(diào)用B類(lèi)的Y字段(緊接著執(zhí)行B類(lèi)的靜態(tài)構(gòu)造函數(shù)),回來(lái)之后再繼續(xù)執(zhí)行A類(lèi)的靜態(tài)夠走啊函數(shù)!
這個(gè)博客中寫(xiě)得也非常的詳細(xì):博客地址網(wǎng)址
?
2013-9-22更新
==當(dāng)?shù)谝淮握{(diào)用靜態(tài)字段時(shí),就會(huì)執(zhí)行所有靜態(tài)字段,并執(zhí)行靜態(tài)構(gòu)造函數(shù),下次再調(diào)用其他靜態(tài)字段時(shí),就直接取即可,不必在執(zhí)行一遍User類(lèi)
==只要使用此類(lèi),例如實(shí)例化,就會(huì)執(zhí)行類(lèi)中的靜態(tài)字段。
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專(zhuān)家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的由单例模式学到:静态构造函数和静态字段的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python学习入门基础教程(learn
- 下一篇: QL Server 中四种匹配符的含义