首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 字符串比較:`==` 比較引用地址,`equals()` 比較內容

     編輯:程式設計綜合問答

代碼現象


String s1 = "a";
s1 += "b";           // s1 現在指向堆中新對象 "ab"
System.out.println(s1 == "ab"); // false

根本原因

  • `==` 比較**引用地址**(棧上的指針值)。
  • `s1 += "b"` 編譯器優化為 `StringBuilder` 拼接,最終 `new String("ab")` 在**堆**創建新對象。
  • 字面量 `"ab"` 在**字符串常量池**(編譯期確定)。
  • 堆對象 ≠ 常量池對象 → 地址不同 → `==` 為 `false`。

內存圖解


棧:                     堆:                     常量池:
s1 ──────────────► 0x7F... "ab" (新對象)       "ab" (常量池對象) ◄── 字面量 "ab"

正確比較方式


// 內容比較
s1.equals("ab")        // true (推薦)
"ab".equals(s1)        // true (防 NPE 寫法)
Objects.equals(s1, "ab") // Java 7+ 工具類,雙向防 NPE

// 如果確定都是常量池對象(極少見)
s1.intern() == "ab"    // 強制進常量池再比地址,不推薦

補充:`String s = new String("a")` vs `String s = "a"`

寫法創建對象數位置s == "a"
`String s = "a";`0 或 1 (常量池)常量池true
`String s = new String("a");`1 (堆) + 0/1 (常量池)堆false
`String s = "a" + "b";`1 (常量池, 編譯期優化)常量池true
`String s = "a"; s += "b";`1 (堆, 運行期)堆false

最佳實踐

永遠用 `equals()` 比較字符串內容,除非極其確定雙方都是常量池引用且需極致性能(極少見)。

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