你知道屬性(字段)與構造函數誰先執行嗎?


     你知道屬性(字段)與構造函數誰先執行嗎?
    最近一直在馬不停蹄的做開發,正所謂學而不思則罔,思而不學則殆,開發過程中其實學到了好多,也發現了好多,但是有時候會因為某些原因沒能深入探討和研究,而只是想當然的處理,今天突然閑心泛濫,想研究下一個類中屬性與構造函數到底哪個先執行,執行順序策略是怎樣的?這個問題其實已經困擾我好久,因為有些整個類中需要使用的一下對象,我有時候喜歡直接在聲明的時候就進行實例化,但是這樣真的好嗎?會不會影響到速度、性能之類的問題?我看過一些別人的代碼,總之,有的將實例化對象放到構造函數中,有的直接實例化,今天就來測試一下它的執行順序。
    真是不看不知道,一看嚇一跳,編程的偉大油然而生,現在按照這樣的順序來敘述本篇文章:為什么要測試---要測試什么---怎么測試---開始測試---別人的看法---結論(溫馨提示,結論不一定是真理)。
    既然測試,那就測試全一點,首先測試實例化與未實例化屬性和構造函數的執行順序,測試未初始化與初始化的屬性和構造函數的執行順序,測試構造函數和未初始化與初始化的屬性的執行順序,測試構造函數和初始化與未初始化的屬性的執行順序,測試構造函數和初始化與未初始化的屬性的執行順序。
    將上述需要測試的地方全部用代碼實現,如下: 

 1 public class SportJudge
 2 {
 3     private DAL.SportJudgeDataContext sj = new DAL.SportJudgeDataContext();
 4     /*先測試初始化與未初始化的屬性和構造函數的執行順序*/
 5     private String test1;                              //沒有初始化
 6     private String test2 = "我被初始化了...";         //初始化
 7     /*先測試初始化與未初始化的屬性和構造函數的執行順序*/
 8  
 9  
10     /*測試未初始化與初始化的屬性和構造函數的執行順序*/
11     private String test3 = "我被初始化了...";         //初始化
12     private String test4;
13     /*測試未初始化與初始化的屬性和構造函數的執行順序*/
14     //默認構造函數
15     public SportJudge()
16     {
17         test8 = "我在構造函數中被初始化了";
18     }
19     /*測試構造函數和未初始化與初始化的屬性的執行順序*/
20     private String test5;
21     private String test6 = "我被初始化了...";
22     /*測試構造函數和未初始化與初始化的屬性的執行順序*/
23  
24     /*測試構造函數和初始化與未初始化的屬性的執行順序*/
25     private String test7 = "我被初始化了...";
26     private String test8;
27     /*測試構造函數和初始化與未初始化的屬性的執行順序*/
28 }

 

將每句話都加上斷點,構造函數加一個斷點就行了,然后開始debug,神奇的事情出現了,所有未實例化的屬性全部沒有被執行,直接無法對未實例化的屬性進行debug,然后其他的執行順序如下:



    網上有人說執行順序一定是構造函數先執行,字段在后面才執行,當然也有說不知道的,總之能正常執行就行了,管他呢。
    基本結論如下:如果字段沒有賦值,則直接跳過,若有賦值,則優先於構造函數執行初始化,不管該字段在構造函數前邊還是后邊。如果有多個字段都有賦值,那么按照代碼從上到下依次執行,所有的字段處理完畢后再執行構造函數。最后想想這樣的執行順序也算是合乎情理,所謂巧婦難為無米之炊嘛,字段就相當於菜、米和調料,是基礎的資源,構造函數就像是一個鍋,而方法則是各種烹飪技術。此種比喻僅為個人看法,算了,我承認我餓了...
    趁熱打鐵,我打開eclipse集成環境,迅速用java編寫同樣的代碼,如下:

 1 public class Test {
 2     /*先測試初始化與未初始化的屬性和構造函數的執行順序*/
 3     private String test1;                              //沒有初始化
 4     private String test2 = "我被初始化了...";         //初始化
 5     /*先測試初始化與未初始化的屬性和構造函數的執行順序*/
 6  
 7  
 8     /*測試未初始化與初始化的屬性和構造函數的執行順序*/
 9     private String test3 = "我被初始化了...";         //初始化
10     private String test4;
11     /*測試未初始化與初始化的屬性和構造函數的執行順序*/
12     public Test(){
13         String test11 = "我是構造函數";
14     }
15     /*測試構造函數和未初始化與初始化的屬性的執行順序*/
16     private String test5;
17     private String test6 = "我被初始化了...";
18     /*測試構造函數和未初始化與初始化的屬性的執行順序*/
19  
20  
21     /*測試構造函數和初始化與未初始化的屬性的執行順序*/
22     private String test7 = "我被初始化了...";
23     private String test8;
24     /*測試構造函數和初始化與未初始化的屬性的執行順序*/
25     public static void main(String[] args) {
26         Test t = new Test();
27     }
28 }

 

 執行順序經測試,與c#類似,但不同的是:java執行的時候,構造函數先執行,【但是】,執行構造函數的時候,程序並沒有進入到構造函數中去,而是執行所有字段,等執行完了之后再回到構造函數,執行構造函數中的代碼塊。其他的順序與C#相同。
 
本人才疏學淺,不對的地方,望批評指正!
作者:楊浩瑞
時間:2015年05月22日 
我的網址是: http://www.yxxrui.cn

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM