首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java equals 與 == 區別徹底解析:從源碼到實戰

     編輯:Java 相關知識

核心結論先行

  • ==:比較引用地址(基本類型比較值)。
  • equals():默認比較引用地址,但常被重寫以比較內容(String、包裝類、集合等)。

基本類型 vs 引用類型

int a = 1, b = 1;
System.out.println(a == b); // true,比較值

Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
System.out.println(i1 == i2);      // false,不同對象地址
System.out.println(i1.equals(i2)); // true,Integer 重寫 equals 比較值

Object 源碼:equals 默認行為

public boolean equals(Object obj) {
    return (this == obj); // 直接比較引用
}

常見類重寫 equals 的邏輯(JDK 8 源碼節選)

類比較邏輯
String先比引用,再比長度,最後逐字符比對 char[] value
Integer/Long/Short/Bytevalue == ((Integer)obj).intValue() 比較內部 int value
Double/Float用 doubleToLongBits 處理 NaN、-0.0 等特殊值
Booleanvalue == ((Boolean)obj).booleanValue()
DategetTime() == ((Date)obj).getTime() 比較毫秒時間戳

實測代碼與輸出

public class EqualsDemo {
    public static void main(String[] args) {
        Integer i1 = new Integer(1), i2 = new Integer(1);
        String s1 = new String("123"), s2 = new String("123");
        Date d1 = new Date(), d2 = new Date(); // 不同毫秒數

        System.out.println("Integer: == " + (i1 == i2) + ", equals " + i1.equals(i2));
        System.out.println("String:  == " + (s1 == s2) + ", equals " + s1.equals(s2));
        System.out.println("Date:    == " + (d1 == d2) + ", equals " + d1.equals(d2));
    }
}
Integer: == false, equals true
String:  == false, equals true
Date:    == false, equals true   // 若 d1/d2 毫秒不同

最佳實踐清單

  1. 基本類型:直接用 ==。
  2. 引用類型比較內容:永遠用 equals(),並注意防空(Objects.equals(a,b) 或 "constant".equals(str))。
  3. 自定義類:必須重寫 equals() 和 hashCode(),遵循對稱性、傳遞性、一致性契約。
  4. 枚舉:可直接用 ==,因為枚舉實例在 JVM 中唯一。

常見坑點

  • List.contains()、Set、Map key 內部均依賴 equals(),未重寫會導致邏輯錯誤。
  • 自動裝箱緩存範圍(-128~127)會讓 Integer a = 100; Integer b = 100; a==b 為 true,切勿依賴此行為。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved