构造代码块会想你所想
上一個建議中我們提議使用構造代碼塊來簡化代碼,并且也了解到編譯器會自動把構造代碼塊插入到各個構造函數中,那我們接下來看看編譯器是不是足夠聰明,能夠為我們解決真實的開發問題。有這樣一個案例:統計一個類的實例數量。可能你要說了,這很簡單,在每個構造函數中加入一個對象計數器不就解決問題了嗎?或者使用我們上一個建議介紹的,使用構造代碼塊也可以。確實如此,我們來看如下代碼是否可行:
1 public class Client { 2 public static void main(String[] args) { 3 new Base(); 4 new Base(""); 5 new Base(0); 6 System.out.println("實例對象數量:" + Base.getNumOfObjects()); 7 } 8 } 9 10 class Base { 11 // 對象計數器 12 private static int numOfObjects = 0; 13 14 { 15 // 構造代碼塊,計算產生對象數量 16 numOfObjects++; 17 } 18 19 public Base() { 20 } 21 22 // 有參構造調用無參構造 23 public Base(String _str) { 24 this(); 25 } 26 27 // 有參構造不調用其他構造 28 public Base(int _i) { 29 } 30 31 // 返回在一個JVM中,創建了多少個實例對象 32 public static int getNumOfObjects() { 33 return numOfObjects; 34 } 35 }這段代碼是可行的嗎?能計算出實例對象的數量嗎?哎,好像不對呀,如果編譯器把構造代碼塊插入到各個構造函數中,那帶有String形參的構造函數可就有問題,它會調用無參構造,那通過它生成Base對象時就會執行兩次構造代碼塊:一次是由無參構造函數調用構造代碼塊,一次是執行自身的構造代碼塊,這樣的話計算可就不準確了,main函數實際在內存中產生了3個對象,但結果卻會是4。不過真是這樣的嗎?Are you sure?我們運行一下看看結果:
實例對象數量:3
非常遺憾,你錯了,實例對象的數量還是3,程序沒有任何問題。奇怪嗎?不奇怪,上一個建議是說編譯器會把構造代碼塊插入到每一個構造函數中,但是有一個例外的情況沒有說明:如果遇到this關鍵字(也就是構造函數調用自身其他的構造函數時)則不插入構造代碼塊,對于我們的例子來說,編譯器在編譯時發現String形參的構造函數調用了無參構造,于是放棄插入構造代碼塊,所以只執行了一次構造代碼塊—結果就是如此。
那Java編譯器為什么會這么聰明呢?這還要從構造代碼塊的誕生說起,構造代碼塊是為了提取構造函數的共同量,減少各個構造函數的代碼而產生的,因此,Java就很聰明地認為把代碼塊插入到沒有this方法的構造函數中即可,而調用其他構造函數的則不插入,確保每個構造函數只執行一次構造代碼塊。
還有一點需要說明,讀者千萬不要以為this是特殊情況,那super也會類似處理了。其實不會,在構造代碼塊的處理上,super方法沒有任何特殊的地方,編譯器只是把構造代碼塊插入到super方法之后執行而已,僅此不同。
注意 放心地使用構造代碼塊吧,Java已經想你所想了。
?
本文轉自SummerChill博客園博客,原文鏈接:http://www.cnblogs.com/DreamDrive/p/5422705.html,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的构造代码块会想你所想的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 0 有符号和无符号整型数字
- 下一篇: [Office 2010 易宝典]怎样直