Java(15)Object類
前言
Object類是Java中所有類的始祖,在Java中每個類都擴展了Object。如果沒有明確地指出超類,Object就被認為是這個類的超類。由於在Java中每個類都是由Object類擴展而來的,所以熟悉這個類提供的所有服務十分重要。
equals方法
equals方法用於檢測一個對象是否等於另外一個對象。在Object類中,equals方法比較的是兩個對象的地址值,地址值相同返回true,否則返回false,以下是其源碼:
public boolean equals(Object obj) {
return (this == obj);
}
==運算符的使用:對於基本數據類型,其比較的是對象的數值;對於引用數據類型,其比較的是對象的地址值。
重寫equals方法
在Object類中,equals方法比較的是兩個對象的地址值,然而這樣的比較意義不大,我們更希望根據兩個對象的屬性值是否相同來判斷這兩個對象是否「相等」,因此我們在自己創建對象時需要重寫equals方法,以下是自己創建的Employee類中的具體重寫程式碼:
public class Employee {
private String name;
private double salary;
private LocalDate hireDay;
// 重寫equals方法,傳入Object對象
public boolean equals(Object otherObject) {
// 若參與比較的兩個對象是同一個對象(地址值相同),直接返回true,只是為了提高程式碼執行效率
if (this == otherObject) {
return true;
}
// 判斷非空
if (otherObject == null) {
return false;
}
// 判斷2個對象是否屬與同一個類
if (getClass() != otherObject.getClass()) {
return false;
}
// 將Object類型強轉成Employee類
Employee other = (Employee) otherObject;
// 返回對象是否相等的結果
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
}
}
objects.equals()
在重寫equals方法的最後使用了Objects.equals()函數,Objects類是JDK7之後添加的一個工具類,它提供了一些方法來操作對象,它由一些靜態的實用方法組成,這些方法是空指針安全的,其中Objects.equals()就是為了防止Object.equals()中容易出現空指針異常的現象
源碼如下:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
編寫equals方法的建議
- 顯示參數命名為
otherObject,稍後需要將它強制轉換成另一個名為other的變數
- 檢測
this與otherObject是否相等:
if (this == otherObject) return true;
這條語句只是一個優化。實際上,這是一種經常採用的形式。因為檢查身份要比逐個比較欄位開銷小。
- 檢測
otherObject是否為null,如果為null,返回false。這項檢測是很有必要的。
if (this == otherObject) return false;
- 比較this與otherObject的類。如果equals的語義可以在子類中改變,就使用
getClass檢測
if (getClass() != otherObject.getClass()) return false;
如果所有的子類都有相同的相等性語義,可以使用instanceof檢測
if (!(otherObject instanceof ClassName)) return false;
- 將otherObject強制轉換為相應類類型的變數:
ClassName other = (ClassName) otherObject
- 根據相等性概念的要求來比較欄位。使用
==比較基本類型欄位,使用Objects.equals比較對象欄位。如果所有的欄位都匹配,就返回true;否則返回false。
如果子類中重新定義equals,就要在其中包含一個super.equals(other)調用
hashCode
散列碼(hash code)是由對象導出的一個整型值。散列碼是沒有規律的。如果x和y是兩個不同的對象,x.hashCode()與y.hashCode()基本上不會相同。
如果重新定義了equals方法,就必須為用戶可能插入散列表的對象重新定義hashCode方法
hashCode方法應該返回一個整數(也可以是負數),並且equals與hashCode的定義必須相容:如果x.equals(y)發那會true,那麼x.hashCode()就必須與y.hashCode()返回相同的值。例如,如果定義Employee.equals比較員工的ID,那麼hashCode方法就需要散列ID,而不是員工的姓名或存儲地址。
toString
在Object中有一個重要的方法,就是toString方法,它會返回表示對象值的一個字元串。默認列印的是類名+哈希編碼的形式,由於這種形式正常人看不懂,所以我們需要重寫這個方法,列印一些容易看都懂的描述資訊。
一般調用方法有2種:
- 當一個引用對象和字元串作連接的時候,會自動調用
toString方法 - 直接列印引用對象
如果類中沒有toString方法,又由於Object類是所有類的超類,所以我們會調用Object中的toString方法,但是默認的列印格式是:類名+哈希編碼,所以我們需要重寫toString方法,最後這裡強烈建議為自定義的每一個類添加toString方法
