廉頗老矣,尚能飯否

          java:從技術到管理

          常用鏈接

          統計

          最新評論

          類的 初始化順序【轉載】

          class ClassA{
              
          static{
                  System.out.println(
          "ClassA's static.");
              }

              
          public ClassA(){
                  System.out.println(
          "ClassA's constructor.");
              }

          }

          class ClassB extends ClassA{
              
          static{
                  System.out.println(
          "ClassB's static.");
              }

              
          public ClassB(){
                  System.out.println(
          "ClassB's constructor.");
              }

          }

          public class TestClass {

              
          public static void main(String[] args) {
                  ClassA a 
          = new ClassB();
                  System.out.println(
          "===============");
                  a 
          = new ClassB();
              }


          }

          輸出:
          ClassA's static.
          ClassB's static.
          ClassA's constructor.
          ClassB's constructor.
          ===============
          ClassA
          's constructor.
          ClassB's constructor.
          我個人分析如下:
          當執行到ClassA a = new ClassB();時開始加載ClassB,這里因為ClassB繼承ClassA,所以加載ClassA,在加載ClassA的時候執行輸出:ClassA's static.。
          ClassA加載完后,加載ClassB,這時執行結果為:ClassB's static.。兩個類都加載完后開始構建對象。
          在構建ClassB對象時,得先構建父類對象ClassA,所以執行分別為:ClassA's constructor.
          ClassB's constructor.那么這句話完了。
           
          到a=new ClassB();時,由于ClassA,ClassB已經被加載過,在內存中。所以只是簡單的進行構建對象。輸出:ClassA's constructor.
          ClassB's constructor.
          希望大家多多指教。
          ============================
          類的初始化分為類加載后的初始化和類實例化后的初始化,當new一個類的時候,如果此類沒有被加載到vm中,vm會先加載此類,當加載完成后vm會立即執 行此類中的所有的靜態初始化代碼。加載完成后,vm會為實例分配內存,然后執行實例初始化代碼,最后是執行構造方法返回新建對象的引用。

          靜態初始化代碼是被static修飾的字段或靜態代碼段,實例初始化代碼是類中聲明并初始化并且沒有被static修飾的字段,還有就是在類中被大括號括起來的代碼段
          ===========================
          關鍵是要把握幾點

          1. 對象實例初始化之前要初始化類實例,它們對應字節碼的方法名分別是 cinit() 和init(),類的靜態塊編譯后會放在 cinit() 方法中,{} 括起來的非靜態塊會放到 init() 方法中。

          2. 構造子對象實例前必須構造出父對象實例,當然在構造子類實例前必須構造父類實例。

          就這么兩點,這里用了類實例和對象實例。區別是,比如有個類A,分別構造了
          A a1 = new A();
          A a2 = new A();
          A a3 = new A();

          三個是對象實例,但是只要同一個類加載器加載的,那么
          a1.getClass()和a2.getClass(),a3.getClass() 就是同一個實例,叫做它們的類實例。

          這里只簡單的說了是由同一個類加載器加的,如果延展開來就會比較復雜。根據類加載器的委托機制和可見性原則還會有不同的情況。


          柳德才
          13691193654
          18942949207
          QQ:422157370
          liudecai_zan@126.com
          湖北-武漢-江夏-廟山

          posted on 2009-03-31 17:26 liudecai_zan@126.com 閱讀(166) 評論(0)  編輯  收藏 所屬分類: 程序人生

          主站蜘蛛池模板: 德格县| 资兴市| 板桥市| 安义县| 华亭县| 罗平县| 怀柔区| 黑龙江省| 德江县| 疏勒县| 方正县| 彩票| 滦平县| 博乐市| 贡山| 土默特右旗| 湘乡市| 静宁县| 会泽县| 平原县| 林西县| 紫阳县| 苍溪县| 浑源县| 年辖:市辖区| 子长县| 泸定县| 黔西| 沈丘县| 和林格尔县| 崇左市| 景谷| 石城县| 红安县| 大渡口区| 抚顺市| 营口市| 怀安县| 枞阳县| 广饶县| 盐城市|