Java 中 String.equals() 的實現邏輯是面試與基礎鞏固的高頻考點。本文結合 JDK 源碼,詳細解析 this 的指向、== 與 equals() 的區別,並通過自定義類 Student 演示重寫 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;
}
this 指向誰?this 永遠指向調用該方法的當前對象實例。例如 str1.equals(str2) 中,this 就是 str1,anObject 是 str2。
this == anObject:若是同一對象,直接返回 true,提升性能。instanceof String:確保參數是 String 類型,避免 ClassCastException。false。value 陣列:確保內容完全一致才返回 true。以下代碼演示 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()正是為了實現「內容相同視為相等」的語義。
equals() 時必須同時重寫 hashCode(),保證放入 HashSet/HashMap 時行為一致。Objects.equals(a, b)(Java 7+)簡化空值判斷與比較邏輯。@EqualsAndHashCode 自動生成,減少樣板代碼。理解 this 指向、引用比較與內容比較的區別,是寫出正確、高效 Java 代碼的基石。