o.equals(o) == trueo.equals(o1) → o1.equals(o)o.equals(o1) ∧ o.equals(o2) → o1.equals(o2)o.equals(null) == false註:以上為 API 規範精簡版,完整定義請參考官方文檔。
Object.equals() 僅比較參考位址(this == obj),即「引用比較」。若需「值比較」,子類別必須覆寫。
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof FieldPosition)) return false;
FieldPosition other = (FieldPosition) obj;
if (attribute == null) {
if (other.attribute != null) return false;
} else if (!attribute.equals(other.attribute)) return false;
return (beginIndex == other.beginIndex
&& endIndex == other.endIndex
&& field == other.field);
}
乍看合理,實則暗藏對稱性破壞風險。
package debug;
import java.text.*;
public class Test {
public static void main(String[] args) {
FieldPosition fp = new FieldPosition(10);
FieldPosition fp1 = new MyTest(10); // 子類別
System.out.println(fp.equals(fp1)); // true
System.out.println(fp1.equals(fp)); // false ← 違反對稱性!
}
}
class MyTest extends FieldPosition {
int x = 10;
public MyTest(int x) { super(x); this.x = x; }
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof MyTest)) return false; // 嚴格檢查自身類別
// ...
}
}
FieldPosition.equals 使用 instanceof FieldPosition,子類別實例通過檢查 → 回傳 trueMyTest.equals 使用 instanceof MyTest,父類別實例失敗 → 回傳 falsefp.equals(fp1) != fp1.equals(fp),嚴重違反契約equals 時,同時覆寫 hashCode,維持雙向一致性getClass() == obj.getClass() 替代 instanceof,確保嚴格類別相等(除非刻意設計跨類別相等)Objects.equals() (JDK 7+) 處理 null 安全比較