gdufo

           

          JAVA面試題解惑系列(一)——類的初始化順序

          轉自:
          http://www.javaeye.com/topic/208187

          大家在去參加面試的時候,經常會遇到這樣的考題:給你兩個類的代碼,它們之間是繼承的關系,每個類里只有構造器方法和一些變量,構造器里可能還有一段代碼對變量值進行了某種運算,另外還有一些將變量值輸出到控制臺的代碼,然后讓我們判斷輸出的結果。這實際上是在考查我們對于繼承情況下類的初始化順序的了解。

          我們大家都知道,對于靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序以此是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器。我們也可以通過下面的測試代碼來驗證這一點:

           1public class InitialOrderTest {   
           2  
           3    // 靜態變量   
           4    public static String staticField = "靜態變量";   
           5    // 變量   
           6    public String field = "變量";   
           7  
           8    // 靜態初始化塊   
           9    static {   
          10        System.out.println(staticField);   
          11        System.out.println("靜態初始化塊");   
          12    }
             
          13  
          14    // 初始化塊   
          15    {   
          16        System.out.println(field);   
          17        System.out.println("初始化塊");   
          18    }
             
          19  
          20    // 構造器   
          21    public InitialOrderTest() {   
          22        System.out.println("構造器");   
          23    }
             
          24  
          25    public static void main(String[] args) {   
          26        new InitialOrderTest();   
          27    }
             
          28}
            
          29

          運行以上代碼,我們會得到如下的輸出結果:
          1. 靜態變量
          2. 靜態初始化塊
          3. 變量
          4. 初始化塊
          5. 構造器

          這與上文中說的完全符合。那么對于繼承情況下又會怎樣呢?我們仍然以一段測試代碼來獲取最終結果:

           1class Parent {   
           2    // 靜態變量   
           3    public static String p_StaticField = "父類--靜態變量";   
           4    // 變量   
           5    public String p_Field = "父類--變量";   
           6  
           7    // 靜態初始化塊   
           8    static {   
           9        System.out.println(p_StaticField);   
          10        System.out.println("父類--靜態初始化塊");   
          11    }
             
          12  
          13    // 初始化塊   
          14    {   
          15        System.out.println(p_Field);   
          16        System.out.println("父類--初始化塊");   
          17    }
             
          18  
          19    // 構造器   
          20    public Parent() {   
          21        System.out.println("父類--構造器");   
          22    }
             
          23}
             
          24  
          25public class SubClass extends Parent {   
          26    // 靜態變量   
          27    public static String s_StaticField = "子類--靜態變量";   
          28    // 變量   
          29    public String s_Field = "子類--變量";   
          30    // 靜態初始化塊   
          31    static {   
          32        System.out.println(s_StaticField);   
          33        System.out.println("子類--靜態初始化塊");   
          34    }
             
          35    // 初始化塊   
          36    {   
          37        System.out.println(s_Field);   
          38        System.out.println("子類--初始化塊");   
          39    }
             
          40  
          41    // 構造器   
          42    public SubClass() {   
          43        System.out.println("子類--構造器");   
          44    }
             
          45  
          46    // 程序入口   
          47    public static void main(String[] args) {   
          48        new SubClass();   
          49    }
             
          50}
            
          51

          運行一下上面的代碼,結果馬上呈現在我們的眼前:
          1. 父類--靜態變量
          2. 父類--靜態初始化塊
          3. 子類--靜態變量
          4. 子類--靜態初始化塊
          5. 父類--變量
          6. 父類--初始化塊
          7. 父類--構造器
          8. 子類--變量
          9. 子類--初始化塊
          10. 子類--構造器
          現在,結果已經不言自明了。大家可能會注意到一點,那就是,并不是父類完全初始化完畢后才進行子類的初始化,實際上子類的靜態變量和靜態初始化塊的初始化是在父類的變量、初始化塊和構造器初始化之前就完成了。

          那么對于靜態變量和靜態初始化塊之間、變量和初始化塊之間的先后順序又是怎樣呢?是否靜態變量總是先于靜態初始化塊,變量總是先于初始化塊就被初始化了呢?實際上這取決于它們在類中出現的先后順序。我們以靜態變量和靜態初始化塊為例來進行說明。

          同樣,我們還是寫一個類來進行測試:
           1public class TestOrder {   
           2    // 靜態變量   
           3    public static TestA a = new TestA();   
           4       
           5    // 靜態初始化塊   
           6    static {   
           7        System.out.println("靜態初始化塊");   
           8    }
             
           9       
          10    // 靜態變量   
          11    public static TestB b = new TestB();   
          12  
          13    public static void main(String[] args) {   
          14        new TestOrder();   
          15    }
             
          16}
             
          17  
          18class TestA {   
          19    public TestA() {   
          20        System.out.println("Test--A");   
          21    }
             
          22}
             
          23  
          24class TestB {   
          25    public TestB() {   
          26        System.out.println("Test--B");   
          27    }
             
          28}
            
          29

          運行上面的代碼,會得到如下的結果:
          1. Test--A
          2. 靜態初始化塊
          3. Test--B

          大家可以隨意改變變量a、變量b以及靜態初始化塊的前后位置,就會發現輸出結果隨著它們在類中出現的前后順序而改變,這就說明靜態變量和靜態初始化塊是依照他們在類中的定義順序進行初始化的。同樣,變量和初始化塊也遵循這個規律。

          了解了繼承情況下類的初始化順序之后,如何判斷最終輸出結果就迎刃而解了。

          posted on 2008-08-22 08:26 gdufo 閱讀(205) 評論(0)  編輯  收藏 所屬分類: JAVA 基礎

          導航

          統計

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 永修县| 昭苏县| 炎陵县| 电白县| 留坝县| 东明县| 宝鸡市| 甘泉县| 湟中县| 福贡县| 拉孜县| 桃江县| 南安市| 铅山县| 曲沃县| 西城区| 黄大仙区| 潮安县| 山阳县| 错那县| 汶上县| 买车| 衡阳县| 哈巴河县| 荆州市| 肥乡县| 廉江市| 宜城市| 利津县| 无锡市| 大足县| 手游| 衡南县| 洱源县| 开鲁县| 木兰县| 白城市| 星子县| 闸北区| 定州市| 临潭县|