從Java類初始化,來看代碼優化

Java類初始化順序可能引起的bug


   最近編程中遇到的問題, 類的成員初始化過程大家都很瞭解,都是基礎知識,但是有些地方很微妙,重新學習

下,來提高代碼質量。


先描述下遇到的場景:

     

  子類構造器中調用super(),然後在父類構造器中調用子類有@overwrite的方法,子類在overwrite的方法中對自己成

賦值,log輸出成功賦值,在子類new完,log打印發現部分成員變量值丟失了。



打印log發現list數據丟失了,int值還在,如下:

  

  看了半天感覺還是很奇怪,有點不相信代碼的感覺,最後debug發現類成員的初始化影響了特殊情況數據的

丟失(重寫賦值)。

  


  下面代碼研究下類成員的初始化,有些特殊而微妙的地方需要注意:



 

執行結果:
















結論:

1繼承體系的所有靜態成員初始化(先父類,後子類)

2父類初始化完成(普通成員的初始化-->構造函數的調用)

3子類初始化(普通成員-->構造函數)


  結合第一個有bug場景例子,可以很清晰的看出,父類構造完後會對子類(需要初始化)的成員進行初始化,這個

時候已經賦值的成員list會重新初始化,然後list數據丟bug就出現了,解決這個問題只要賦值放在子類自己構造器裏

(成員初始化後),問題就解決了。

  

  那麼問題來了,爲什麼同樣是成員變量的intValue沒有數據丟失呢? 繼續初始化分析debug,發現非靜態成員,

如果沒有顯式初始化賦值的話,相應類型的數據有默認的初始值(int類型爲0,引用類型爲null)。在類非靜態成員

初始化過程中,不會對這些值顯示賦值,所以上面例子中intValue在父類構造器中賦值後,數據能夠保留下來。so,

子中bug, 簡單的解決辦法還可以直接把定義地方的顯示賦值去掉就ok了。


後話:

   1.java類中類是動態加載的,static成員可以在類未被實例化而使用,且對於靜態變量在內存中只有一個拷貝(節省存),JVM

只爲靜態分配一次內存,在加載類的過程中完成靜態變量的內存分配。在類初始化時,減少類初始化步驟,對代碼優化有一定提

高。

  2.類成員的操作儘量要在自己類中調用操作,要儘量複合類設計原則:單一職責。不要產生過多複雜的引用關係,產生bug

才能夠儘快分析出原因。

  3.類非靜態成員定義時,如果業務邏輯允許,儘量不要對其定義時賦值,這樣,類在構造的時候就可以少很多初始化步驟,

加快類的初始化。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章