posts - 188,comments - 176,trackbacks - 0


          類Person和子類Son,體現(xiàn)對象初始化流程的代碼:

          public class Person {
              Bow b1 
          = new Bow(1);
              
          static {
                  System.out.println(
          "Person staticstatic塊1");
              }

              
          {
                  System.out.println(
          "Person hello非static塊1");
              }

              Bow b2 
          = new Bow(2);
              
          static Bow b3 = new Bow(3);
              Person() 
          {
                  System.out.println(
          "PersonPerson類的構(gòu)造器");
              }

              
          {
                  System.out.println(
          "Person hello非static塊2");
              }

              
          static {
                  System.out.println(
          "Person staticstatic塊2");
              }

          }

          class Son extends Person {
              Bow b4 
          = new Bow(4);
              
          static {
                  System.out.println(
          "Test staticstatic塊1");
              }

              
          {
                  System.out.println(
          "Test hello1非static塊1");
              }

              Bow b5 
          = new Bow(5);
              
          static Bow b6 = new Bow(6);
              Son() 
          {
                  System.out.println(
          "TestTest類的構(gòu)造器");
              }

              
          {
                  System.out.println(
          "Test hello2非static塊2");
              }

              
          static {
                  System.out.println(
          "Test static2static塊2");
              }

              
          public static void main(String[] args) {
                  System.out.println(
          "main");
                  
          new Son();
              }

          }

          class Bow {
              Bow(
          int m) {
                  System.out.println(
          "Bow(" + m + ")");
              }

          }

          執(zhí)行結(jié)果:
          Person static...static塊1
          Bow(3)
          Person static...static塊2
          Test static...static塊1
          Bow(6)
          Test static2...static塊2
          main...
          Bow(1)
          Person hello...非static塊1
          Bow(2)
          Person hello...非static塊2
          Person...Person類的構(gòu)造器
          Bow(4)
          Test hello1...非static塊1
          Bow(5)
          Test hello2...非static塊2
          Test...Test類的構(gòu)造器


          從上面結(jié)果,可以總結(jié)出JAVA對象初始化的流程:
           【1】父類static塊和父類static屬性(兩者的執(zhí)行先后順序依據(jù)它們在類中具體位置由上至下)
           【2】子類static塊和子類static屬性(兩者的執(zhí)行先后順序依據(jù)它們在類中具體位置由上至下)
           【3】執(zhí)行main方法中new關(guān)鍵字之前的代碼塊
           【4】父類非static塊執(zhí)行和父類非static屬性(兩者的執(zhí)行先后順序依據(jù)它們在類中具體位置由上至下,如果屬性為實例類型,則執(zhí)行該實例所在類的非static塊和非static屬性,再執(zhí)行該類的構(gòu)造器,即[4][5]步驟)
           【5】父類構(gòu)造器(完成非static屬性初始值的設(shè)置) 
           【6】子類非static塊執(zhí)行和子類非static屬性(兩者的執(zhí)行先后順序依據(jù)它們在類中具體位置由上至下,如果屬性為實例類型,則執(zhí)行該實例所在類的非static塊和非static屬性,再執(zhí)行該類的構(gòu)造器,即[6][7]步驟)
           【7】子類構(gòu)造器(完成非static屬性初始值設(shè)置,如果在子類構(gòu)造器執(zhí)行前就返回該非static屬性,則該非static屬值為屬性默認(rèn)值
             注:針對第【7】點“子類構(gòu)造器執(zhí)行前就返回該非static屬性”,具體可以見下例:
          public class ParentObjectInit {

              
          public void test() {

              }

              
          public ParentObjectInit() {
                  test();
              }

          }

          class ChildObjectInit extends ParentObjectInit {
              
          private int instanceValue = 20;
              
          public void test() {
                  System.out.println(
          "instance1 value : " + instanceValue);
              }

              
          public static void main(String[] args) {
                  
          new ChildObjectInit();
              }

          }
          這段代碼的執(zhí)行結(jié)果:
          instance1 value is: 0 因為new 子類ChildObjectInit時,會先初始化父類ParentObjectInit,繼而調(diào)用父來構(gòu)造器器,接著執(zhí)行此構(gòu)造器中的test()方法,基于多態(tài)性,會轉(zhuǎn)而調(diào)用子類的test()方法執(zhí)行子類test()方法代碼體,打印出instanceValue的屬性默認(rèn)值。(因為此時打印instanceValue值后,父類構(gòu)造器才執(zhí)行結(jié)束返回,根本還沒輪到子類的初始化工作和子類構(gòu)造器的執(zhí)行。)
          posted on 2008-05-24 21:26 cheng 閱讀(2205) 評論(3)  編輯  收藏 所屬分類: JBS

          FeedBack:
          # re: 對象初始化流程梳理
          2008-05-25 15:12 | 隔葉黃鶯
          1. 初始化分為為的初始化和實例的初始化
          2. 每個類在 JVM 中都對應(yīng)一個 Class 實例
          3. 父類實例是作為子例的部分存在的 (Class 實例之間也存在父子關(guān)系)
          4. 初始化實例之前要初始化類

          基于以上幾點就可以理解以下初始化順序
          1. 父類靜態(tài)屬性、靜態(tài)類 (父類的初始化,對應(yīng) JVM 方法 cinit())
          2. 子類的靜態(tài)屬性、靜態(tài)類 (子類的初始化,對應(yīng) JVM 方法 cinit())
          3. 父類的實例構(gòu)造,實例變量初始化 (實例變量初始實際會放到 JVM 的 init() 中)
          4. 子類的實例構(gòu)造,實例變量初始化 (也是對應(yīng)的 init() 方法)

          關(guān)于類的 Class 實例,可以回想 Log 的聲明
          Log log = LogFactory.getLog(TestClass.class);
          也就是無論你,new 多少個 TestClass 實例,它們對應(yīng)著同一個 TestClass 的 Class 實例,也就是為什么很多地方把靜態(tài)方法、靜態(tài)屬性說成是類的方法、類的屬性,其實質(zhì)就是在 JVM 中存在同一個 Class 實例的方法、屬性,也就能保持一致性。

          關(guān)于父類實例是作為子類的一部分存在,可借鑒 C++ 或是有面向?qū)ο筇匦缘?C 函數(shù)庫(如 gtk),來理解,父類實例會居于子類實例的首地址,所以對子類轉(zhuǎn)型成父類實例時,它是安全的,因為首地址一樣的,所以從首地址到 size(父類)就是父類實例地址空間,到size(子類)就是子類實例的地址空間。  回復(fù)  更多評論
            
          # re: 對象初始化流程梳理
          2008-05-26 14:32 | cheng
          看過樓上朋友見解,體會又深一層,謝謝。  回復(fù)  更多評論
            
          # re: 對象初始化流程梳理
          2008-05-26 14:32 | Happy漫步者
          不錯 收藏了  回復(fù)  更多評論
            
          主站蜘蛛池模板: 噶尔县| 阳谷县| 运城市| 彭阳县| 建宁县| 华容县| 禄丰县| 泸西县| 晴隆县| 象州县| 屏南县| 东光县| 土默特左旗| 和林格尔县| 涞源县| 越西县| 太和县| 水城县| 轮台县| 铜山县| 平舆县| 宝坻区| 鹤岗市| 新丰县| 门头沟区| 樟树市| 上林县| 元谋县| 张北县| 仪征市| 连平县| 桃园县| 寻甸| 柞水县| 南宫市| 仁布县| 墨脱县| 紫金县| 昆山市| 宜兰市| 孝感市|