Java構造器必知必會
在麵向對象編程中,編程人員應該在意“資源”。比如
String hello = "hello";
在代碼中,我們很在意在內存中String類型的hello,它是有一個生命周期的。在它生命周期中,初始化(initialization)和清理(cleanup)是兩個重要的環節。尤其是C程序中,很多bug會出現在對象初始化和清理的環節。這樣會造成一些程序安全問題。
《Think in Java》中說道:
隨著計算機革命的發展,”不安全“的編程方式已逐漸成為編程代價高昂的主因之一。
一、棧與堆
在Java開發中,針對對象會在乎內存的兩個區域:對象的生存空間是堆(heap) — 方法調用及局部變量(也稱棧變量)的生存空間棧(stack)。如圖:
二、什麼是構造器,默認(無參)構造器
為了保證對象成功初始化,Java像C++一樣引入了構造器(Constructor),即在創建對象的時候被自動調用的特殊方法。自然,Java額外提供了GC(垃圾回收器),對於不再使用的資源,垃圾回收機製會自動釋放資源。Java通過類構造器創建新對象的時候,在使用此對象前,會調用其構造器進行初始化。如:
public class VoidConstructor {
VoidConstructor(){
// 構造器
}
void VoidConstructor() {
// void 方法,不是構造器
}
}
1、默認構造器
這裏,VoidConstructor是一個類,如果需要創建一個VoidConstructor對象隻要
VoidConstructor constr = new VoidConstructor();
調用上麵的代碼就可以通過這個默認構造器(即無參構造器),就生成一個VoidConstuctor對象。代碼圖解如下
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:
上麵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函數運行結果如下:
1. 先分析下類UML,ChildConstructor 繼承 PersonConstructor,PersonConstructor 繼承 Object:
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. 過程流程圖詳解(圖中是各對象引用在堆棧塊):
五、總結
構造器雖小,關鍵還是非常關鍵的。
本文小結:
1、默認構造器
2、有參構造器
3、繼承中的構造器
還有第一點的知識基礎補充
歡迎點擊我的博客及GitHub — 博客提供RSS訂閱哦!
———- https://www.bysocket.com/ ————- https://github.com/JeffLi1993 ———-
最後更新:2017-05-22 13:31:54