閱讀880 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java構造器必知必會

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

String hello = "hello"; 

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

《Think in Java》中說道:

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

一、棧與堆

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

繪圖1

 

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

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

public class VoidConstructor {

VoidConstructor(){
// 構造器
}

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

1、默認構造器

這裏,VoidConstructor是一個類,如果需要創建一個VoidConstructor對象隻要

VoidConstructor constr = new VoidConstructor();

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

繪圖2

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 as — java application

image

上麵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函數運行結果如下:

image

 

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

 

繪圖3

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. 過程流程圖詳解(圖中是各對象引用在堆棧塊):

繪圖4

五、總結

 

 

 

 

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

本文小結:

1、默認構造器

2、有參構造器

3、繼承中的構造器

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

 

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

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

最後更新:2017-05-22 13:31:54

  上一篇:go  Apache Storm 官方文檔 —— 源碼組織結構
  下一篇:go  Apache Storm 官方文檔 —— Ack 框架的實現