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方法的建議

  1. 顯示參數命名為otherObject,稍後需要將它強制轉換成另一個名為other的變數
     
  2. 檢測this與otherObject是否相等:
if (this == otherObject) return true;

  這條語句只是一個優化。實際上,這是一種經常採用的形式。因為檢查身份要比逐個比較欄位開銷小。

  1. 檢測otherObject是否為null,如果為null,返回false。這項檢測是很有必要的。
if (this == otherObject) return false;
  1. 比較this與otherObject的類。如果equals的語義可以在子類中改變,就使用getClass檢測
if (getClass() != otherObject.getClass()) return false;

  如果所有的子類都有相同的相等性語義,可以使用instanceof檢測

if (!(otherObject instanceof ClassName)) return false;
  1. 將otherObject強制轉換為相應類類型的變數:
ClassName other = (ClassName) otherObject
  1. 根據相等性概念的要求來比較欄位。使用==比較基本類型欄位,使用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方法

Tags: