gdufo

           

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

          轉(zhuǎn)自:
          http://www.javaeye.com/topic/208187

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

          我們大家都知道,對(duì)于靜態(tài)變量、靜態(tài)初始化塊、變量、初始化塊、構(gòu)造器,它們的初始化順序以此是(靜態(tài)變量、靜態(tài)初始化塊)>(變量、初始化塊)>構(gòu)造器。我們也可以通過下面的測(cè)試代碼來(lái)驗(yàn)證這一點(diǎn):

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

          運(yùn)行以上代碼,我們會(huì)得到如下的輸出結(jié)果:
          1. 靜態(tài)變量
          2. 靜態(tài)初始化塊
          3. 變量
          4. 初始化塊
          5. 構(gòu)造器

          這與上文中說(shuō)的完全符合。那么對(duì)于繼承情況下又會(huì)怎樣呢?我們?nèi)匀灰砸欢螠y(cè)試代碼來(lái)獲取最終結(jié)果:

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

          運(yùn)行一下上面的代碼,結(jié)果馬上呈現(xiàn)在我們的眼前:
          1. 父類--靜態(tài)變量
          2. 父類--靜態(tài)初始化塊
          3. 子類--靜態(tài)變量
          4. 子類--靜態(tài)初始化塊
          5. 父類--變量
          6. 父類--初始化塊
          7. 父類--構(gòu)造器
          8. 子類--變量
          9. 子類--初始化塊
          10. 子類--構(gòu)造器
          現(xiàn)在,結(jié)果已經(jīng)不言自明了。大家可能會(huì)注意到一點(diǎn),那就是,并不是父類完全初始化完畢后才進(jìn)行子類的初始化,實(shí)際上子類的靜態(tài)變量和靜態(tài)初始化塊的初始化是在父類的變量、初始化塊和構(gòu)造器初始化之前就完成了。

          那么對(duì)于靜態(tài)變量和靜態(tài)初始化塊之間、變量和初始化塊之間的先后順序又是怎樣呢?是否靜態(tài)變量總是先于靜態(tài)初始化塊,變量總是先于初始化塊就被初始化了呢?實(shí)際上這取決于它們?cè)陬愔谐霈F(xiàn)的先后順序。我們以靜態(tài)變量和靜態(tài)初始化塊為例來(lái)進(jìn)行說(shuō)明。

          同樣,我們還是寫一個(gè)類來(lái)進(jìn)行測(cè)試:
           1public class TestOrder {   
           2    // 靜態(tài)變量   
           3    public static TestA a = new TestA();   
           4       
           5    // 靜態(tài)初始化塊   
           6    static {   
           7        System.out.println("靜態(tài)初始化塊");   
           8    }
             
           9       
          10    // 靜態(tài)變量   
          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

          運(yùn)行上面的代碼,會(huì)得到如下的結(jié)果:
          1. Test--A
          2. 靜態(tài)初始化塊
          3. Test--B

          大家可以隨意改變變量a、變量b以及靜態(tài)初始化塊的前后位置,就會(huì)發(fā)現(xiàn)輸出結(jié)果隨著它們?cè)陬愔谐霈F(xiàn)的前后順序而改變,這就說(shuō)明靜態(tài)變量和靜態(tài)初始化塊是依照他們?cè)陬愔械亩x順序進(jìn)行初始化的。同樣,變量和初始化塊也遵循這個(gè)規(guī)律。

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

          posted on 2008-08-22 08:26 gdufo 閱讀(199) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA 基礎(chǔ)

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(6)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          Hibernate

          友情鏈接

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 江孜县| 东乡县| 天台县| 建湖县| 司法| 巴彦县| 东至县| 礼泉县| 梨树县| 上蔡县| 南岸区| 从化市| 雷州市| 涟源市| 肇东市| 台州市| 永善县| 四川省| 辽宁省| 凌云县| 宝丰县| 泗阳县| 刚察县| 漳浦县| 紫金县| 寻甸| 郑州市| 博客| 邯郸市| 彭山县| 贺兰县| 长宁区| 锡林郭勒盟| 梁河县| 西盟| 墨玉县| 宾川县| 富源县| 中方县| 城口县| 巴东县|