剖析一個java對象初始化順序問題

今天我在Dzone閱讀了一篇關于java對象實例初始化順序的有趣文章新锈。說它有趣妄讯,是因為作者使用了一種并不太推薦的編碼風格,只有用這種編碼風格才能觸發(fā)這個極為少見的 Java object initialization order 問題凭疮。

其實java對象初始化順序算是一個比較基礎的java知識點西壮。但是網(wǎng)上的文章多半描述不清,使用上一不小心就容易出問題张咳。

所以在本文中帝洪,我想結(jié)合JLS和自己的理解,舉例剖析問題的所在晶伦。

OK碟狞,我們先來看個模仿Dzone作者原意的簡單例子:

[java]

package com.kenwublog.tmp;

public class A extends B {

public int a = 100;

public A() {

super();

System.out.println(a);

a = 200;

}

public static void main(String[] args) {

System.out.println(new A().a);

}

}

class B {

public B() {

System.out.println(((A) this).a);

}

}

[/java]

例子代碼很簡單啄枕,不多做解釋了婚陪,直接看輸出:

0

100

200

對照這個輸出,我們來詳細分析一下對象的初始化順序:

1频祝,為A類分配內(nèi)存空間泌参,初始化所有成員變量為默認值,包括primitive類型(int=0,boolean=false,…)和Reference類型常空。

2沽一,調(diào)用A類構(gòu)造函數(shù)。

3漓糙,調(diào)用B類構(gòu)造函數(shù)铣缠。

4,調(diào)用Object空構(gòu)造函數(shù)昆禽。(java編譯器會默認加此構(gòu)造函數(shù)蝗蛙,且object構(gòu)造函數(shù)是個空函數(shù),所以立即返回)

5醉鳖,初始化B類成員變量捡硅,因為B類沒有成員變量,跳過盗棵。

6壮韭,執(zhí)行sysout輸出子類A的成員變量小a。// 此時為0

7纹因,初始化A類成員變量喷屋,將A類成員變量小a賦值100。

8瞭恰,執(zhí)行sysout輸出當前A類的成員變量小a逼蒙。// 此時為100

9,賦值當前A類的成員變量小a為200。

10是牢,main函數(shù)中執(zhí)行sysout僵井,輸出A類實例的成員變量小a。// 此時為200

加粗的那兩行描述是重點驳棱,結(jié)論是成員變量初始化是在父類構(gòu)造函數(shù)調(diào)用完后批什,在此之前,成員變量的值均是默認值社搅。Dzone作者就是栽在這里驻债,沒有仔細分析成員變量初始化在對象初始化中的順序,造成了程序未按原意執(zhí)行形葬。

其實這類問題合呐,熟悉原理是一方面,本質(zhì)上只要不在構(gòu)造函數(shù)中插入過多的業(yè)務邏輯笙以,出問題的概率也會低很多淌实。

最后,我們再來看看JLS中給出的Java類對象初始化順序定義猖腕,這是一個帶條件分支的流程描述:

Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.

If this constructor begins with an explicit constructor invocation of another constructor in the same class (usingthis), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.

This constructor does not begin with an explicit constructor invocation of another constructor in the same class (usingthis). If this constructor is for a class other thanObject, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (usingsuper). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.

Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5. (In some early implementations, the compiler incorrectly omitted the code to initialize a field if the field initializer expression was a constant expression whose value was equal to the default initialization value for its type.)

Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.

引用自section 12.5 of the Java Language Spec

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拆祈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子倘感,更是在濱河造成了極大的恐慌放坏,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件老玛,死亡現(xiàn)場離奇詭異淤年,居然都是意外死亡,警方通過查閱死者的電腦和手機蜡豹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門麸粮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人余素,你說我怎么就攤上這事豹休。” “怎么了桨吊?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵威根,是天一觀的道長。 經(jīng)常有香客問我视乐,道長洛搀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任佑淀,我火速辦了婚禮留美,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己谎砾,他們只是感情好逢倍,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著景图,像睡著了一般较雕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挚币,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天亮蒋,我揣著相機與錄音,去河邊找鬼妆毕。 笑死慎玖,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的笛粘。 我是一名探鬼主播趁怔,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闰蛔!你這毒婦竟也來了痕钢?” 一聲冷哼從身側(cè)響起图柏,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤序六,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚤吹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體例诀,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年裁着,在試婚紗的時候發(fā)現(xiàn)自己被綠了繁涂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡二驰,死狀恐怖扔罪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桶雀,我是刑警寧澤矿酵,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站矗积,受9級特大地震影響全肮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棘捣,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一辜腺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦评疗、人聲如沸测砂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邑彪。三九已至,卻和暖如春胧华,著一層夾襖步出監(jiān)牢的瞬間寄症,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工矩动, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留有巧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓悲没,卻偏偏與公主長得像篮迎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子示姿,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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