分享一道大多數(shù)人都會做錯的JVM題

有關(guān)Java虛擬機類加載機制相關(guān)的文章一搜一大把丐谋,筆者這里也不必再贅述一遍了芍碧。筆者這里撈出一道code題要各位大佬來把玩把玩,如果你一眼就看出了端倪号俐,那么恭喜你泌豆,你可以下山了:

public class StaticTest
{
   public static void main(String[] args)
   {
       staticFunction();
   }

   static StaticTest st = new StaticTest();

   static
   {
       System.out.println("1");
   }

   {
       System.out.println("2");
   }

   StaticTest()
   {
       System.out.println("3");
       System.out.println("a="+a+",b="+b);
   }

   public static void staticFunction(){
       System.out.println("4");
   }

   int a=110;
   static int b =112;
}

問題:請問這段程序的輸出是什么?一般對于這類問題吏饿,小伙伴們腦海中肯定浮現(xiàn)出這樣的知識點:

Java中賦值順序

父類的靜態(tài)變量賦值
自身的靜態(tài)變量賦值
父類成員變量賦值和父類塊賦值
父類構(gòu)造函數(shù)賦值
自身成員變量賦值和自身塊賦值
自身構(gòu)造函數(shù)賦值
按照這個理論輸出是什么呢踪危?答案輸出:1 4,這樣正確囍砺洹贞远?肯定不正確啦,這里不是說上面的規(guī)則不正確笨忌,而是說不能簡單的套用這個規(guī)則蓝仲。 正確的答案是:

2
3
a=110,b=0
1
4

有沒有答對呢?這里主要的點之一:實例初始化不一定要在類初始化結(jié)束之后才開始初始化。 類的生命周期是:加載->驗證->準(zhǔn)備->解析->初始化->使用->卸載袱结,只有在準(zhǔn)備階段和初始化階段才會涉及類變量的初始化和賦值亮隙,因此只針對這兩個階段進行分析;

類的準(zhǔn)備階段需要做是為類變量分配內(nèi)存并設(shè)置默認值擎勘,因此類變量st為null咱揍、b為0;(需要注意的是如果類變量是final棚饵,編譯時javac將會為value生成ConstantValue屬性煤裙,在準(zhǔn)備階段虛擬機就會根據(jù)ConstantValue的設(shè)置將變量設(shè)置為指定的值,如果這里這么定義:static final int b=112,那么在準(zhǔn)備階段b的值就是112噪漾,而不再是0了硼砰。)

類的初始化階段需要做的是執(zhí)行類構(gòu)造器(類構(gòu)造器是編譯器收集所有靜態(tài)語句塊和類變量的賦值語句按語句在源碼中的順序合并生成類構(gòu)造器,對象的構(gòu)造方法是()欣硼,類的構(gòu)造方法是()题翰,可以在堆棧信息中看到),因此先執(zhí)行第一條靜態(tài)變量的賦值語句即st = new StaticTest ()诈胜,此時會進行對象的初始化豹障,對象的初始化是先初始化成員變量再執(zhí)行構(gòu)造方法,因此打印2->設(shè)置a為110->執(zhí)行構(gòu)造方法(打印3,此時a已經(jīng)賦值為110焦匈,但是b只是設(shè)置了默認值0血公,并未完成賦值動作),等對象的初始化完成后繼續(xù)執(zhí)行之前的類構(gòu)造器的語句缓熟,接下來就不詳細說了累魔,按照語句在源碼中的順序執(zhí)行即可。

這里面還牽涉到一個冷知識够滑,就是在嵌套初始化時有一個特別的邏輯垦写。特別是內(nèi)嵌的這個變量恰好是個靜態(tài)成員,而且是本類的實例彰触。 這會導(dǎo)致一個有趣的現(xiàn)象:“實例初始化竟然出現(xiàn)在靜態(tài)初始化之前”梯投。 其實并沒有提前,你要知道java記錄初始化與否的時機况毅⊥砘铮看一個簡化的代碼,把關(guān)鍵問題解釋清楚:

public class Test {
   public static void main(String[] args) {
       func();
   }
   static Test st = new Test();
   static void func(){}
}

根據(jù)上面的代碼俭茧,有以下步驟:

1.首先在執(zhí)行此段代碼時咆疗,首先由main方法的調(diào)用觸發(fā)靜態(tài)初始化。
2.在初始化Test 類的靜態(tài)部分時母债,遇到st這個成員午磁。
3.但湊巧這個變量引用的是本類的實例尝抖。
4.那么問題來了,此時靜態(tài)初始化過程還沒完成就要初始化實例部分了迅皇。是這樣么昧辽?
5.從人的角度是的。但從java的角度登颓,一旦開始初始化靜態(tài)部分搅荞,無論是否完成,后續(xù)都不會再重新觸發(fā)靜態(tài)初始化流程了框咙。
6.因此在實例化st變量時咕痛,實際上是把實例初始化嵌入到了靜態(tài)初始化流程中,并且在樓主的問題中喇嘱,嵌入到了靜態(tài)初始化的起始位置茉贡。這就導(dǎo)致了實例初始化完全至于靜態(tài)初始化之前。這也是導(dǎo)致a有值b沒值的原因者铜。
7.最后再考慮到文本順序腔丧,結(jié)果就顯而易見了。

詳細看到這里作烟,心中大概有個結(jié)論了吧愉粤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拿撩,隨后出現(xiàn)的幾起案子衣厘,更是在濱河造成了極大的恐慌,老刑警劉巖绷雏,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異怖亭,居然都是意外死亡涎显,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門兴猩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來期吓,“玉大人,你說我怎么就攤上這事倾芝√智冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵晨另,是天一觀的道長潭千。 經(jīng)常有香客問我,道長借尿,這世上最難降的妖魔是什么刨晴? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任屉来,我火速辦了婚禮,結(jié)果婚禮上狈癞,老公的妹妹穿的比我還像新娘茄靠。我一直安慰自己,他們只是感情好蝶桶,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布慨绳。 她就那樣靜靜地躺著,像睡著了一般真竖。 火紅的嫁衣襯著肌膚如雪脐雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天疼邀,我揣著相機與錄音喂江,去河邊找鬼。 笑死旁振,一個胖子當(dāng)著我的面吹牛获询,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拐袜,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼吉嚣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹬铺?” 一聲冷哼從身側(cè)響起尝哆,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甜攀,沒想到半個月后秋泄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡规阀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年恒序,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谁撼。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡歧胁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厉碟,到底是詐尸還是另有隱情喊巍,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布箍鼓,位于F島的核電站崭参,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏款咖。R本人自食惡果不足惜阵翎,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一逢并、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧郭卫,春花似錦砍聊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至词疼,卻和暖如春俯树,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贰盗。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工许饿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舵盈。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓陋率,卻偏偏與公主長得像,于是被迫代替她去往敵國和親秽晚。 傳聞我的和親對象是個殘疾皇子瓦糟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容