前言
最近在看多線程祥得,講到單例模式安全問題的時(shí)候兔沃。提到了單例的第四種模式——InnerClass模式。里面提到這種是用的最多的方式级及。很好奇里面的寫法乒疏,然后就對靜態(tài)內(nèi)部類加載產(chǎn)生了疑問。故寫了以下的代碼實(shí)驗(yàn)一下饮焦。
代碼1
我們利用靜態(tài)代碼塊隨著類的加載而執(zhí)行這一特征怕吴,對靜態(tài)內(nèi)部類進(jìn)行了測試。
public class StaticClassTest {
static {
System.out.println("this is static outter calss");
}
?
public static class Innclass {
static {
System.out.println("this is static inner class");
}
}
?
public static void main(String[] args) {
new StaticClassTest();//修改在這里
System.out.println("------------我是華麗的分割線-----------");
new StaticClassTest.Innclass();
}
?
}
?```
這段代碼的運(yùn)行結(jié)果是
this is static outter calss
------------我是華麗的分割線-----------
this is static inner class
?```
這里面看到先是外部類加載县踢,然后在調(diào)用內(nèi)部類創(chuàng)建對象的時(shí)候转绷,才會去加載靜態(tài)內(nèi)部類。這點(diǎn)和靜態(tài)成員隨著類一起加載有出入硼啤。而后议经,我對代碼進(jìn)行一些修改。
代碼2
public class OutterClassTest {
?
public static void main(String[] args) {
new Outter();//修改在這里
System.out.println("-------我是華麗的分割線--------");
new Outter.Inner();
}
?
}
?
class Outter {
static {
System.out.println("this is outter class loading ");
}
public static class Inner {
static {
System.out.println("this is inner calss loading ");
}
}
}
這段代碼我將靜態(tài)類的外部類和測試類分開谴返。執(zhí)行主方法后煞肾,得到如下結(jié)果:
this is outter class loading
-------我是華麗的分割線--------
this is inner calss loading
這和上面一段代碼沒什么區(qū)別。但是嗓袱,當(dāng)我們將調(diào)用外部類的方法創(chuàng)建對象這句話分別注釋掉的時(shí)候籍救。其結(jié)果就發(fā)生了變化:
代碼1
this is static outter calss
------------我是華麗的分割線-----------
this is static inner class
?```
代碼2
-------我是華麗的分割線--------
this is inner calss loading
##總結(jié)
很明顯在這里面,代碼1由于是main函數(shù)所在的類渠抹,必須加載蝙昙。所以,靜態(tài)代碼塊先執(zhí)行梧却。沒什么問題奇颠。但主要問題在代碼2上,為什么直接調(diào)用靜態(tài)內(nèi)部類創(chuàng)建對象的時(shí)候篮幢,外部類都沒有加載大刊。
這說明,靜態(tài)內(nèi)部類作為一種特殊的類成員有如下兩個(gè)特征:
1. 加載時(shí)間隨著調(diào)用而加載三椿。而不是和外部類一起加載缺菌。
2. 靜態(tài)內(nèi)部類作為一個(gè)類,是可以單獨(dú)使用搜锰,而不需要加載任何外部類代碼的伴郁。
以上是我對靜態(tài)內(nèi)部類特性的一些總結(jié),如有錯(cuò)誤蛋叼,歡迎指正焊傅。謝謝