首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

深度解析 Java String.equals 源碼與 this 指向、對象比較機制

     編輯:程式設計綜合問答

Java 中 String.equals() 的實現邏輯是面試與基礎鞏固的高頻考點。本文結合 JDK 源碼,詳細解析 this 的指向、== 與 equals() 的區別,並通過自定義類 Student 演示重寫 equals() 時的對象比較細節。

String.equals 源碼解讀

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i]) return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

關鍵點解析

  1. 第二行 this 指向誰?
    this 永遠指向調用該方法的當前對象實例。例如 str1.equals(str2) 中,this 就是 str1,anObject 是 str2。
  2. 先比引用 this == anObject:若是同一對象,直接返回 true,提升性能。
  3. 類型檢查 instanceof String:確保參數是 String 類型,避免 ClassCastException。
  4. 長度相同才逐字符比較:優化性能,長度不同直接返回 false。
  5. 逐字符比較底層 value 陣列:確保內容完全一致才返回 true。

擴展案例:自定義類重寫 equals()

以下代碼演示 Student 類重寫 equals(),並對比 == 與 equals() 的行為差異:

public class EqualsTest {
    public static void main(String[] args) {
        Student s1 = new Student("zhangsan");
        Student s2 = new Student("zhangsan");

        System.out.println(s1 == s2);        // false,比較引用(堆內存地址不同)
        System.out.println(s1.equals(s2));   // true,比較內容(name 相同)
    }
}

class Student {
    String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) return true;                    // 引用相同
        if (anObject instanceof Student) {                    // 類型匹配
            Student student = (Student) anObject;             // 向下轉型
            return student.name.equals(this.name);            // 內容比較
        }
        return false;
    }
}

運行結果解析

false
true
  • s1 == s2:false。new 了兩次,在堆中創建兩個不同對象,引用地址不同。
  • s1.equals(s2):true。進入重寫的 equals(),this 是 s1,anObject 是 s2。student.name 取的是 s2.name,this.name 是 s1.name,兩者均為 "zhangsan",String.equals() 返回 true。

常見誤區釐清

問: student.name.equals(this.name) 中的 student.name 指的是 s1 還是 s2?

答: 指的是 s2。因為 student 是將 anObject(即 s2)強轉後的變量,而 this 是調用者 s1。

問: new 了兩個對象,為什麼 equals 能返回 true?

答: == 比較引用地址,equals() 比較業務邏輯內容。重寫 equals() 正是為了實現「內容相同視為相等」的語義。

最佳實踐建議

  1. 重寫 equals() 時必須同時重寫 hashCode(),保證放入 HashSet/HashMap 時行為一致。
  2. 使用 Objects.equals(a, b)(Java 7+)簡化空值判斷與比較邏輯。
  3. 考慮使用 Lombok @EqualsAndHashCode 自動生成,減少樣板代碼。

理解 this 指向、引用比較與內容比較的區別,是寫出正確、高效 Java 代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved