| 比較方式 | 基本類型 | 引用類型 |
|---|---|---|
== | 比較值 | 比較堆內存地址(引用是否指向同一對象) |
equals() | 不可用(編譯錯誤) | 默認比較地址;常用類已重寫比較內容(String、Integer、Date 等) |
// 基本類型:棧內存直接存值
int a = 10;
int b = 10;
a == b; // true,值相等
// 引用類型:棧存引用,堆存對象
Person p1 = new Person("張三", 25);
Person p2 = new Person("張三", 25);
Person p3 = p1;
p1 == p2; // false,不同堆對象,地址不同
p1 == p3; // true,同一引用指向同一堆對象
// Object 源碼
public boolean equals(Object obj) {
return (this == obj); // 默認就是比較地址
}
重寫規範(自反性、對稱性、傳遞性、一致性、非空性):
equals(),必須重寫 hashCode(),保證相等對象哈希碼相等(HashMap/HashSet 正確工作前提)。EqualsBuilder。// String:比較字符序列
String s1 = "hello";
String s2 = "hello"; // 常量池同一對象
String s3 = new String("hello"); // 堆新對象
s1 == s2; // true
s1 == s3; // false
s1.equals(s2); // true
s1.equals(s3); // true
// Integer:-128~127 緩存池
Integer i1 = 100;
Integer i2 = 100; // 緩存池同一對象
Integer i3 = 200;
Integer i4 = 200; // 超出緩存範圍,新對象
i1 == i2; // true
i3 == i4; // false
i3.equals(i4); // true
public class Person {
private String name;
private int age;
// 構造器、getter/setter 省略
@Override
public boolean equals(Object o) {
if (this == o) return true; // 同一引用快速返回
if (o == null || getClass() != o.getClass()) return false; // 類型檢查
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name); // 內容比較
}
@Override
public int hashCode() {
return Objects.hash(name, age); // 與 equals 使用同一字段
}
}
"constant".equals(variable) 避免變量為 null 時拋 NPE。==。equals(),前提是類已正確重寫(JDK 標準庫、主流第三方庫均已重寫)。==(如枚舉、單例、緩存池對象)。equals() 和 hashCode(),基於業務主鍵或唯一業務字段比較。深入理解 == 與 equals 的語義差異與底層機制,是編寫正確、高效 Java 代碼的基石,也是面試高頻考點。