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

Java 核心基石:== 與 equals() 的本質區別與正確使用姿勢

     編輯:Java 相關知識

== 與 equals() 是 Java 比較操作的雙子星,混淆二者是新手高頻 Bug 來源。本文從記憶體模型、源碼實現、String/包裝類特例三個維度徹底釐清。

本質區別:引用 vs 內容

操作符/方法比較對象語義
==引用地址是否為同一個物件實例(堆中同一塊記憶體)
equals()物件內容是否代表邏輯上「相等」的實體(需類覆寫實現)

預設行為:Object.equals() 就是 ==

// java.lang.Object
public boolean equals(Object obj) {
    return (this == obj);
}

若類未覆寫 equals(),則等同於 ==。

String 為何「特殊」?

String s1 = new String("abc");
String s2 = new String("abc");
s1 == s2;        // false:兩個 new 出來的不同實例
s1.equals(s2);   // true:String 覆寫 equals 比較字符序列

java.lang.String 覆寫 equals() 逐字符比較值,而非引用。

常量池優化導致的「反直覺」現象


String s3 = "abc";
String s4 = "abc";
s3 == s4;        // true!編譯期常量池優化,指向同一實例
s3.equals(s4);   // true

字面量 "abc" 編譯期進入常量池,同值只存一份。new String("abc") 強制在堆創建新實例。

正確使用守則

  1. 比較基本類型:只用 ==。
  2. 比較物件邏輯相等性:永遠用 equals(),前提是該類正確覆寫(如 String、包裝類、集合、自定義 Entity)。
  3. 比較物件同一性:用 ==(如單例檢查、Enum 比較、同步鎖對象)。
  4. 自定義類覆寫 equals() 契約:自反性、對稱性、傳遞性、一致性、非空性。必須同時覆寫 hashCode(),否則作為 Map Key/Set 元素會失效。

經典面試題


String s1 = new String("s1");
String s2 = new String("s1");
// 創建了幾個 String 物件?
// 答:3 個。常量池 1 個("s1"),堆 2 個(new 出來的)。

String s1 = "s1";
String s2 = s1;
s2 = "s2";
// s1 指向的物件內容是?
// 答:"s1"。字符串不可變,s2 重新賦值只改變引用指向,不影響原物件。

記住:== 問「是不是同一個」,equals() 問「值不值一樣」。分清身份與價值,是寫出正確 Java 代碼的起點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved