== 比較的是記憶體地址(引用)或基本型別數值;equals() 是物件邏輯相等性,預設行為同 ==,常被覆寫(String、包裝類、集合、自訂實體)。
| 類型 | == | equals() | 備註 |
|---|---|---|---|
| 基本型別 | 數值比較(自動拓寬) | N/A(無方法) | 1 == 1.0f → true |
| 引用型別 | 地址比較(同一物件) | 預設同 ==;常覆寫為內容比較 | new String("a") == new String("a") → false |
| String | 地址比較 | 逐字元比較內容 | 常量池字面量 "a" == "a" → true |
| 包裝類 | 地址比較 | 數值比較(Integer(1).equals(1) → true) | Integer -128~127 快取導致 == 偶爾 true |
| 自訂類 | 地址比較 | 需自行覆寫 equals/hashCode | 配合 Lombok @Data 或 IDE 生成 |
public boolean equals(Object anObject) {
if (this == anObject) return true; // 1. 同引用快速返回
if (anObject instanceof String) { // 2. 型別檢查
String another = (String) anObject;
if (value.length != another.value.length) return false; // 3. 長度不同直接 false
for (int i = 0; i < value.length; i++) // 4. 逐字元比較
if (value[i] != another.value[i]) return false;
return true;
}
return false;
}
可見 equals 內部首先呼叫 ==,再做內容比較。
String s1 = "a"; String s2 = "a"; // 同池 → == true;new String("a") 強制建立堆上新物件。Integer a = 127, b = 127; a==b → true;Integer c = 128, d = 128; c==d → false。永遠用 equals 比較包裝類數值。"a".equals(null) → false 安全;null.equals("a") → NPE。習慣寫 "const".equals(var) 或 Objects.equals(a,b)(JDK 7+)。equals 必須同時覆寫 hashCode,否則在 HashMap/HashSet 中失效。基本型別看數值,引用型別看地址。
equals 比內容,String 包裝類已改寫。
自訂類別要覆寫,hashCode 一定要配合。
null 怕拋常量在前,Objects.equals 最安穩。