標籤:工作原理 封裝 ofo 返回 就會 關鍵字 局部變數 poi 計算
《Java從小白到大牛》紙質版已經上架了!!!
類執行個體化可產生對象,執行個體方法就是對象方法,執行個體變數就是對象屬性。一個對象的生命週期包括三個階段:建立、使用和銷毀。前面章節已經多少用到了對象,這一章詳細介紹一下對象的建立和銷毀等相關知識。
建立對象
建立對象包括兩個步驟:聲明和執行個體化。
1. 聲明
聲明對象與聲明普通變數沒有區別,文法格式如下:
type objectName;
其中type是參考型別,即類、介面和數組。範例程式碼如下:
String name;
該語句聲明了字串類型對象name。可以聲明並不為對象分配記憶體空間,而只是分配一個引用。
2. 執行個體化
執行個體化過程分為兩個階段:為對象分配記憶體空間和初始化對象,首先使用new運算子為對象分配記憶體空間,然後再調用構造方法初始化對象。範例程式碼如下:
String name;name = new String("Hello World");
代碼中String("Hello World")運算式就是調用String的構造方法。初始化完成之後11-1所示。
Null 物件
一個引用變數沒有通過new分配記憶體空間,這個對象就是Null 物件,Java使用關鍵字null表示Null 物件。範例程式碼如下:
String name = null;name = "Hello World";
引用變數預設值是null。當試圖調用一個Null 物件的執行個體變數或執行個體方法時,會拋出null 指標異常NullPointerException,如下代碼所示:
String name = null;//輸出null字串System.out.println(name);//調用length()方法int len = name.length(); ①
但是代碼運行到第①行時,系統會拋出異常。這是因為調用length()方法時,name是Null 物件。程式員應該避免調用Null 物件的成員變數和方法,代碼如下:
//判斷對象是否為nullif (name != null) {int len = name.length();}
提示 產生Null 物件有兩種可能性:第一是程式員自己忘記了執行個體化,第二是Null 物件是別人傳遞給我們的。第一種程式員必須防止這種情況發生,應該仔細檢查自己的代碼,為自己建立的所有對象進行執行個體化並初始化。第二種情況需要通過判斷對象非null進行避免。
構造方法
在11.1節使用了運算式new String("Hello World"),其中String("Hello World")是調用構造方法。構造方法是類中特殊方法,用來初始化類的執行個體變數,這個就是構造方法,它在建立對象(new運算子)之後自動調用。
Java構造方法的特點:
- 構造方法名必須與類名相同。
- 構造方法沒有任何傳回值,包括void。
- 構造方法只能與new運算子結合使用。
構造方法範例程式碼如下:
//Rectangle.java檔案package com.a51work6;// 矩形類public class Rectangle {// 矩形寬度int width;// 矩形高度int height;// 矩形面積int area;// 構造方法public Rectangle(int w, int h) { ①width = w;height = h;area = getArea(w, h);}...}
代碼第①行是聲明了一個構造方法,其中有兩個參數w和h,用來初始化Rectangle對象的兩個成員變數width和height,注意前面沒有任何的傳回值。
預設構造方法 {#-0}
有時在類中根本看不到任何的構造方法。例如本節中User類代碼如下:
//User.java檔案package com.a51work6;public class User {// 使用者名稱private String username;// 使用者密碼private String password;}
從上述User類代碼,只有兩個成員變數,看不到任何的構造方法,但是還是可以調用無參數的構造方法建立User對象,見如下代碼。
//HelloWorld.java檔案...User user = new User();
Java虛擬機器為沒有構造方法的類,提供一個無參數的預設構造方法,預設構造方法其方法體內無任何語句,預設構造方法相當於如下代碼:
//預設構造方法public User() {}
預設構造方法的方法體內無任何語句,也就不能夠初始化成員變數了,那麼這些成員變數就會使用預設值,成員變數預設值是與資料類型有關,具體內容可以參考9.1.2節中的表9-1所示。這裡不再贅述。
構造方法重載 {#-1}
在一個類中可以有多個構造方法,它們具體有相同的名字(與類名相同),參數列表不同,所以它們之間一定是重載關係。
構造方法重載範例程式碼如下:
//Person.java檔案package com.a51work6;import java.util.Date;public class Person {// 名字private String name;// 年齡private int age;// 出生日期private Date birthDate;public Person(String n, int a, Date d) { ①name = n;age = a;birthDate = d;}public Person(String n, int a) { ②name = n;age = a;}public Person(String n, Date d) { ③name = n;age = 30;birthDate = d;}public Person(String n) { ④name = n;age = 30;}public String getInfo() {StringBuilder sb = new StringBuilder();sb.append("名字: ").append(name).append('\n');sb.append("年齡: ").append(age).append('\n');sb.append("出生日期: ").append(birthDate).append('\n');return sb.toString();}}
上述代碼Person類代碼提供了4個重載的構造方法,如果有準確的姓名、年齡和出生日期資訊,則可以選用代碼第①行的構造方法建立Person對象;如果只有姓名和年齡資訊則可選用代碼第②行的構造方法建立Person對象;如果只有姓名和出生日期資訊則可選用代碼第③行的構造方法建立Person對象;如果只有姓名資訊則可選用代碼第④行的構造方法建立Person對象。
構造方法封裝 {#-2}
構造方法也可以進行封裝,存取層級與普通方法一樣,構造方法的存取層級參考表11-1所示。範例程式碼如下:
//Person.java檔案package com.a51work6;import java.util.Date;public class Person {// 名字private String name;// 年齡private int age;// 出生日期private Date birthDate;// 公有層級限制public Person(String n, int a, Date d) { ①name = n;age = a;birthDate = d;}// 預設層級限制Person(String n, int a) { ②name = n;age = a;}// 保護層級限制protected Person(String n, Date d) { ③name = n;age = 30;birthDate = d;}// 私人層級限制private Person(String n) { ④name = n;age = 30;}...}
上述代碼第①行是聲明公有層級的構造方法。代碼第②行是聲明預設層級,預設層級只能在同一個包中訪問。代碼第③行是保護層級的構造方法,該構造方法在同一包中與預設層級相同,在不同包中可以被子類繼承。代碼第④行是私人層級構造方法,該構造方法只能在當前類中使用,不允許在外邊訪問,私人構造方法可以應用於單例設計模式^10等設計。
this關鍵字 {#this}
前面章節中使用過this關鍵字,this指向對象本身,一個類可以通過this來獲得一個代表它自身的物件變數。this使用在如下三種情況中:
- 調用執行個體變數。
- 調用執行個體方法。
- 調用其他構造方法。
使用this變數的範例程式碼:
//Person.java檔案package com.a51work6;import java.util.Date;public class Person {// 名字private String name;// 年齡private int age;// 出生日期private Date birthDate;// 三個參數構造方法public Person(String name, int age, Date d) { ①this.name = name; ②this.age = age; ③birthDate = d;System.out.println(this.toString()); ④}public Person(String name, int age) {// 調用三個參數構造方法this(name, age, null); ⑤}public Person(String name, Date d) {// 調用三個參數構造方法this(name, 30, d); ⑥}public Person(String name) {// System.out.println(this.toString());// 調用Person(String name, Date d)構造方法this(name, null); ⑦}@Overridepublic String toString() {return "Person [name=" + name ⑧+ ", age=" + age ⑨+ ", birthDate=" + birthDate + "]";}}
上述代碼中多次用到了this關鍵字,下面詳細分析一下。代碼第①行聲明三個參數構造方法,其中參數name和age與執行個體變數name和age命名衝突,參數是範圍為整個方法的局部變數,為了防止局部變數與成員變數命名發生衝突,可以使用this調用局部變數,見代碼第②行和第③行。注意代碼第⑧行和第⑨行的name和age變數沒有衝突,所以可以不使用this調用。
this也可以調用本對象的方法,見代碼第④行的this.toString()語句,這本例中this可以省略。
在多個構造方法重載時,一個構造方法可以調用其他的構造方法,這樣可以減少代碼量,上述代碼第⑤行this(name, age, null)使用this調用其他構造方法。類似調用還有代碼第⑥行的this(name, 30, d)和第⑦行的this(name, null)。
注意 使用this調用其他構造方法時,this語句一定是該構造方法的第一條語句。例如在代碼第⑦行之前調用toString()方法則會發生錯誤。
對象銷毀
對象不再使用時應該銷毀。C++語言對象是通過delete語句手動釋放,Java語言對象是由記憶體回收行程(Garbage Collection)收集然後釋放,程式員不用關係釋放的細節。自動記憶體管理是現代電腦語言發展趨勢,例如:C#語言的記憶體回收,Objective-C和Swift語言的ARC(記憶體自動引用計數管理)。
記憶體回收行程(Garbage Collection)的工作原理是:當一個對象的引用不存在時,認為該對象不再需要,記憶體回收行程自動掃描對象的動態記憶體區,把沒有引用的對象作為垃圾收集起來並釋放。
本章小結
通過對本章的學習,可以瞭解如何建立Java對象,理解構造方法的作用。此外,還介紹了this關鍵的使用。
配套視頻
http://edu.51cto.com/topic/1246.html
配套原始碼
http://www.zhijieketang.com/group/5
《Java從小白到大牛》之第11章 對象