圖解 & 深入淺出Java初始化與清理:構造器必知必會

jopen 9年前發布 | 10K 次閱讀 Java Java開發

Writer :BYSocket(泥沙磚瓦漿木匠)

微 博:BYSocket

豆 瓣:BYSocket

非死book:BYSocket

推ter :BYSocket

面向對象編程中,編程人員應該在意“資源”。比如

String hello = "hello";

在代碼中,我們很在意在內存String類型hello,它是有一個生命周期的。在它生命周期中,初始化(initialization)清理(cleanup)是兩個重要的環節。尤其是C程序中,很多bug會出現在對象初始化清理的環節。這樣會造成一些程序安全問題。

《Think in Java》中說道:

隨著計算機革命的發展,”不安全“的編程方式已逐漸成為編程代價高昂的主因之一。

一、棧與堆

在Java開發中,針對對象會在乎內存的兩個區域:對象的生存空間是堆(heap) 方法調用及局部變量(也稱變量)的生存空間棧(stack)。如圖:

圖解 & 深入淺出Java初始化與清理:構造器必知必會

 

二、什么是構造器,默認(無參)構造器

為了保證對象成功初始化,Java像C++一樣引入了構造器(Constructor),即在創建對象的時候被自動調用的特殊方法。自然,Java額外提供了GC(垃圾回收器),對于不再使用的資源,垃圾回收機制會自動釋放資源。Java通過類構造器創建新對象的時候,在使用此對象前,會調用其構造器進行初始化。如:

public class VoidConstructor {

    VoidConstructor(){
        // 構造器
    }

    void VoidConstructor() {
        // void 方法,不是構造器
    }
}

1、默認構造器

這里,VoidConstructor是一個類,如果需要創建一個VoidConstructor對象只要

VoidConstructor constr = new VoidConstructor();

調用上面的代碼就可以通過這個默認構造器(即無參構造器),就生成一個VoidConstuctor對象。代碼圖解如下

圖解 & 深入淺出Java初始化與清理:構造器必知必會

2、注意,構造器特殊方法,采取與類名同名。它沒有返回值,這與返回值void方法不同。這里,void方法名命名也是不規范,應該是“每個方法首字母小寫”,也一般不與類名相同。

另外,就算你類沒有寫構造器的話,編譯器會生成一個默認構造器。

三、帶參構造器

下面跑個帶參構造器的例子:

/**
 * @author Jeff Lee
 * @since 2015-9-7 16:54:19
 * 帶參數簡單構造器的展示
 */
public class SimpleConstructor2 {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Child2(i);
        }
    }
}

// Child類
class Child2 {
    Child2(int i) {// 帶參數的Child類構造器
        System.out.print("Child init " + i + " ");
    }
}

Eclipse中,右鍵Run asjava application

圖解 & 深入淺出Java初始化與清理:構造器必知必會

上面Child2(int)是Child類的唯一構造器,此時你先在編譯器中通過 new Child2()來創建對象是不行的。

所以,構造器有助于避免開發中出現代碼錯誤

二者,構造器可以用來初始化資源。其中,對象的創建與資源的初始化是捆綁在一起的。

休息一下吧~ 看看小廣告:

開源代碼都在我的gitHub上哦 — https://github.com/JeffLi1993 作者留言“請手賤,點項目star,支持支持拜托拜托

四、繼承中的構造器

在創建一個對象時,所以繼承下來的對象都會被調用各構造器。比如說下面這個例子:

/**
 * @author Jeff Lee
 * @since 2015-9-10 08:56:18
 * 繼承中的構造器的案例
 */
public class ChildConstructor extends PersonConstructor{
    ChildConstructor() {
 //super(); 
        System.out.println("Making a Child Modle...");
    }

    @SuppressWarnings("unused")
    public static void main(String[] args) {
        ChildConstructor childConstructor = new ChildConstructor();
    }
}

class PersonConstructor {
    PersonConstructor() {
        System.out.println("Making a Person Modle...");
    }
}

main函數運行結果如下:

圖解 & 深入淺出Java初始化與清理:構造器必知必會

 

1. 先分析下類UML,ChildConstructor 繼承 PersonConstructor,PersonConstructor 繼承 Object:

 

圖解 & 深入淺出Java初始化與清理:構造器必知必會

2. super關鍵字,super用來調用父類的構造器。如果子類中沒有super關鍵字,編譯器會自動添加默認super()方法。因此,子類通過super()方法調用父類構造器。

3. 然后main函數中,通過new指令,啟動了ChildConstructor對象的創建。子類 ChildConstructor 構造器在執行時,第一件事通過super()調用父類,這又會連鎖反應到Objerct類。所以,打印控制臺先輸出 “父類先初始化”。

這過程就是構造器鏈Constructor Chaining),即Child對象 is-a Person對象同時也 is-a Object對象。如果創建Child對象,也同時創建了Person對象和Object對象的部分。

4. 過程流程圖詳解(圖中是各對象構造器在堆棧塊中調用流程 圖中引用兩字有歧義):

圖解 & 深入淺出Java初始化與清理:構造器必知必會

五、總結

 

構造器雖小,關鍵還是非常關鍵的。

本文小結:

1、默認構造器

2、有參構造器

3、繼承中的構造器

還有第一點的知識基礎補充

 

歡迎點擊我的博客及GitHub — 博客提供RSS訂閱哦!

———- http://www.bysocket.com/ ————- https://github.com/JeffLi1993 ———-



 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!