Java語言基礎:對象的初始化

來源:互聯網
上載者:User

1.  如果基類存在預設建構函式,則在子類構造之前,會先調用基類的預設建構函式:

class A {<br /> A() {<br /> System.out.println("A create");<br /> }<br />}</p><p>class B extends A {<br /> B() {<br /> // 會在這裡先調用A的預設建構函式<br /> System.out.println("B create");<br /> }<br />}</p><p>class C extends A {<br /> C(int i) {<br /> // 會在這裡先調用A的預設建構函式<br /> System.out.println("C create");<br /> }<br />}</p><p>public class Main {<br /> public static void main(String[] args) {<br /> B b = new B();<br /> C c = new C(10);<br /> }<br />}</p><p>// 輸出為:<br />A create<br />B create<br />A create<br />C create<br />

 

 

2.  如果基類只有帶參數的建構函式,子類必須在自己的建構函式中通過super(...)顯式調用該基類建構函式:

 

class A {<br /> A(int i) {<br /> System.out.println("A create");<br /> }<br />}</p><p>class B extends A {<br /> B() {<br /> // 必須在這裡顯式調用父類的非預設建構函式,否則編譯不通過<br /> // 注意這調用只能放在最前面,否則編譯不通過<br /> super(20);<br /> System.out.println("B create");<br /> }<br />}</p><p>class C extends A {<br /> C(int i) {<br /> // 必須在這裡顯式調用父類的非預設建構函式,否則編譯不通過<br /> // 注意這調用只能放在最前面,否則編譯不通過<br /> super(30);<br /> System.out.println("C create");<br /> }<br />}</p><p>public class Main {<br /> public static void main(String[] args) {<br /> B b = new B();<br /> C c = new C(10);<br /> }<br />}<br />// 輸出為:<br />A create<br />B create<br />A create<br />C create<br />

3.  以上只講了最簡單的建構函式調用順序,其實一個對象的真正的初始化過程應該是:

  1. 將對象的儲存空間初始化為二進位的0.
  2. 先遞迴到最上層的基類去,將最上層的基類作為當前類。
  3. 對於當前類:
    1. 按聲明順序調用成員變數的初始設定代碼。
    2. 調用建構函式。
  4. 接著將下一層繼承類作為當前類,繼續步驟3

     

    先看下面的代碼:

    class A {<br /> A() {<br /> System.out.println("A create");<br /> }<br />}</p><p>class D {<br /> D() {<br /> System.out.println("D create");<br /> }<br />}</p><p>class B extends A {<br /> private D d = new D();<br /> B() {<br /> System.out.println("B create");<br /> }<br />}</p><p>class C extends B {<br /> C(int i) {<br /> System.out.println("C create");<br /> }<br />}</p><p>public class Main {<br /> public static void main(String[] args) {<br /> C c = new C(10);<br /> }<br />}<br /> 

    初始化過程大概是這樣的:

    1.  先從C遞迴到B,再從B遞迴到A。
    2. A沒有成員變數,所以A的建構函式被調用。
    3. 接到回到B,B有一個D類的成員有初始化,因此D的建構函式被調用。
    4. 接著B的建構函式被調用。
    5. 最後回到C,C的建構函式被調用。

      所以輸出應該是:

      A create

      D create

      B create

      C create

       

      4.  必須小心在建構函式中調用虛函數(在JAVA裡普通函數都是虛的)的隱患,特別是在基類的建構函式,因為此時繼承類的成員可能還沒有初始完畢:

      class A {<br /> A() {<br /> System.out.println("A create");<br /> proc();<br /> }<br /> public void proc() {<br /> }<br />}</p><p>class B extends A {<br /> private int i;<br /> B() {<br /> System.out.println("B create");<br /> i = 10;<br /> }<br /> public void proc(){<br /> System.out.println(i);<br /> }<br />}</p><p>public class Main {<br /> public static void main(String[] args) {<br /> B b = new B();<br /> }<br />}<br />輸出:<br />A create<br />0<br />B create<br /> A的建構函式調用了proc,此時B的建構函式還沒有被調用,因此i還沒有被賦為10,最終輸出結果是0。

       

      5.  由於Java對象都是通過記憶體回收機制清理對象,因此Java的類沒有解構函式,遇到需要清理類中資源的問題時,可以自己聲明一個函數,如Dispose,在適當的時候調用之。

      相關文章

      聯繫我們

      該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

      如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

      A Free Trial That Lets You Build Big!

      Start building with 50+ products and up to 12 months usage for Elastic Compute Service

      • Sales Support

        1 on 1 presale consultation

      • After-Sales Support

        24/7 Technical Support 6 Free Tickets per Quarter Faster Response

      • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.