千里冰封
          JAVA 濃香四溢
          posts - 151,comments - 2801,trackbacks - 0

          記得在剛學(xué)JAVA的時(shí)候,類的加載機(jī)制和初始化順序經(jīng)常被弄的糊里糊涂,其實(shí)當(dāng)我們不太了解某些事情的時(shí)候,不防去做一做實(shí)驗(yàn),讓代碼的運(yùn)行結(jié)果說(shuō)話,這或許能幫助我們更好地了解一些事情.今天我們就用一些代碼來(lái)看一下類是如何被加載的,并且當(dāng)有繼承關(guān)系的時(shí)候,類的加載順序又是怎么樣的.

          先看代碼吧

          /*
           * Test4.java
           * 
           * Created on 2007-9-21, 9:33:31
           * 
           * To change this template, choose Tools | Templates
           * and open the template in the editor.
           
          */

          package test1;

          /**
           *
           * 
          @author hadeslee
           
          */
          public class Test4 {
              
          private void testClassForName(String name) throws ClassNotFoundException{
                  Class c
          =Class.forName(name);
              }
              
          private void testNewInstance(String name) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
                  Class c
          =Class.forName(name);
                  Object obj
          =c.newInstance();
                  System.out.println(obj);
              }
              
          public static void main(String[] args)throws Exception {
                  Test4 t
          =new Test4();
                  t.testClassForName(
          "test1.B");
                  
          new B();
                  
          new B();
              }
          }
          class A{
              
          private int aj;
              {
                  aj
          =20;
                  System.out.println(
          "A成員初始化塊");
              }
              
          private static int ai;
              
          static {
                  ai
          =10;
                  System.out.println(
          "A靜態(tài)初始化塊");
              }
              
          public A(){
                  System.out.println(
          "A構(gòu)造函數(shù)");
              }
          }
          class B extends A{
              
          private static int bi;
              
          static {
                  bi
          =30;
                  System.out.println(
          "B靜態(tài)初始化塊");
              }
              
          private  int bj;
              {
                  bj
          =40;
                  System.out.println(
          "B成員初始化塊");
              }
              
          public B(){
                  System.out.println(
          "B構(gòu)造函數(shù)");
              }
          }

          在代碼里面我們總共有三個(gè)類,一個(gè)是做測(cè)試用的Test4,一個(gè)是A,一個(gè)是A的子類B,我們?cè)贏和B類里面都有很多輸出,一個(gè)是靜態(tài)初始化的輸出,一個(gè)是成員初始化的輸出,一個(gè)是在構(gòu)造函數(shù)里面的輸出,從這些輸出我們可以知道代碼的執(zhí)行順序,以上代碼運(yùn)行輸出如下:

          A靜態(tài)初始化塊
          B靜態(tài)初始化塊
          A成員初始化塊
          A構(gòu)造函數(shù)
          B成員初始化塊
          B構(gòu)造函數(shù)
          A成員初始化塊
          A構(gòu)造函數(shù)
          B成員初始化塊
          B構(gòu)造函數(shù)


          從上面我們可以看出,A和B的靜態(tài)初始化塊只被執(zhí)行了一次,也就是類的對(duì)象將要被生成的時(shí)候,它會(huì)執(zhí)行,并且執(zhí)行的順序如下:父類的靜態(tài)成員,子類的靜態(tài)成員,父類的成員變量和構(gòu)造方法,子類的成員變量和構(gòu)造方法.當(dāng)再用這個(gè)類生成對(duì)象的時(shí)候,靜態(tài)的部份就不再被調(diào)用了.因?yàn)殪o態(tài)是類的所有實(shí)例所共享的,所以它在整個(gè)虛擬機(jī)的生命周期內(nèi)只執(zhí)行一次.

          如果我們加上一個(gè)t.testClassForName("test1.B");放在main函數(shù)的最后面,我們會(huì)發(fā)現(xiàn)輸出還是和剛剛一樣,沒(méi)有任何改變,這個(gè)時(shí)候,我們知道,當(dāng)我們調(diào)用Class.forName(name);的時(shí)候,類是不會(huì)自動(dòng)初始化的,它默認(rèn)只是把這個(gè)類的字節(jié)碼讀入內(nèi)存,但是并沒(méi)有初始化這個(gè)類.只有我們調(diào)用了newInstance()的時(shí)候,它才會(huì)被初始化.在這里我們?cè)龠@樣試一下:把A和B生成的class文件去掉,然后再分別調(diào)用Class.forName和new B(),看看會(huì)怎么樣,我們會(huì)發(fā)現(xiàn)當(dāng)我們調(diào)用Class.forName的時(shí)候,當(dāng)我們要for的Name找不到的時(shí)候,只會(huì)拋出ClassNotFoundException,注意,它只是一個(gè)異常而已,而當(dāng)我們new B()的時(shí)候,B的class文件卻被我們刪掉了,那就事大了,那就將拋出NoClassDefFoundError,呵呵,它就是一個(gè)Error了,這點(diǎn)區(qū)別我們可要注意啦,當(dāng)我們?cè)谧鲞@些事情的時(shí)候,一個(gè)只要捕獲異常就可以了,一個(gè)卻需要捕獲一個(gè)Error,一般來(lái)說(shuō),Error級(jí)別的錯(cuò)誤是不希望程序員去捕獲的.了解了類的基本加載順序以及加載機(jī)制后,對(duì)我們了解JAVA是有一定的幫助的.好了,先講這些吧,有關(guān)類的加載機(jī)制以后再繼續(xù)分享:)


          盡管千里冰封
          依然擁有晴空

          你我共同品味JAVA的濃香.
          posted on 2007-09-21 09:59 千里冰封 閱讀(1677) 評(píng)論(2)  編輯  收藏 所屬分類: JAVASE

          FeedBack:
          # re: 類加載機(jī)制初探
          2007-09-21 13:34 | 久城
          哈哈,讓我想起三個(gè)月前,我的畢業(yè)設(shè)計(jì)就是這個(gè)...  回復(fù)  更多評(píng)論
            
          # re: 類加載機(jī)制初探
          2008-01-25 00:24 | damagegod
          畢業(yè)設(shè)計(jì)寫這個(gè)?  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 易门县| 东源县| 安仁县| 西乌珠穆沁旗| 金堂县| 顺义区| 沐川县| 高邮市| 威信县| 宁海县| 兴业县| 巴彦淖尔市| 呈贡县| 晋州市| 辛集市| 浙江省| 湖北省| 高州市| 岐山县| 门头沟区| 崇明县| 饶阳县| 襄垣县| 拜城县| 安顺市| 渝中区| 威信县| 来安县| 鄂温| 陆川县| 房山区| 金沙县| 任丘市| 申扎县| 青浦区| 石城县| 武功县| 昌吉市| 辽宁省| 松原市| 石阡县|