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

Java 字符串比較陷阱:== 與 equals() 的區別導致訂單 ID 賦值失敗

     編輯:程式設計疑難解答

Java 新手最易犯的錯誤:使用 == 比較字符串內容。本文透過一個訂單分組實戰案例,演示 == 導致邏輯失效的全過程,並給出正確姿勢。

問題場景

  • 購物車商品:0、1、2 屬店鋪 A (shopId="100"),3 屬店鋪 B (shopId="200")
  • 期望:同店鋪商品共用一個 orderId,不同店鋪分單
  • 現象:只有商品 0 得到 orderId,商品 1、2 的 orderId 為 null

錯誤代碼


String currentShopId = null;
String currentOrderId = null;

for (CartItem item : cartItems) {
    // ❌ 致命錯誤:== 比較字符串引用而非內容
    if (item.getShopId() == currentShopId) { 
        item.setOrderId(currentOrderId);
    } else {
        currentShopId = item.getShopId();
        currentOrderId = generateOrderId();
        item.setOrderId(currentOrderId);
    }
}

為什麼會失敗?

結果:同店鋪商品被拆分為多個訂單,且因邏輯分支錯亂導致部分 orderId 未正確賦值 (null)。

正確代碼


String currentShopId = null;
String currentOrderId = null;

for (CartItem item : cartItems) {
    // ✅ 使用 equals() 比較內容
    // ✅ 使用 Objects.equals() 防空指針 (Java 7+)
    if (Objects.equals(item.getShopId(), currentShopId)) {
        item.setOrderId(currentOrderId);
    } else {
        currentShopId = item.getShopId();
        currentOrderId = generateOrderId();
        item.setOrderId(currentOrderId);
    }
}

核心知識點總結

  1. == 比較引用地址:只有指向堆中同一對象時才為 true
  2. equals() 比較內容:String 重寫了 equals,逐字符比較值
  3. 字符串常量池機制:
    • 字面量 "abc" 編譯期入池,同值共用引用
    • new String("abc")、運行時拼接、網絡/文件讀取創建的字符串在堆中新建對象
    • String.intern() 可手動入池
  4. 最佳實踐:
    
    // Java 7+ 推薦
    Objects.equals(str1, str2); // 內部處理 null,調用 str1.equals(str2)
    
    // 或者
    "constant".equals(variable); // 常量在前,防 NPE
    

擴展:其他包裝類同理

迴圈輪次item.shopIdcurrentShopId== 結果說明
1"100" (對象A)nullfalse進入 else,生成 orderId_1,currentShopId 指向對象A
2"100" (對象B)對象Afalse字符串常量池/新對象,引用不同! 進入 else,重新生成 orderId_2
3"100" (對象C)對象Bfalse同理,生成 orderId_3
4"200" (對象D)對象Cfalse生成 orderId_4
類型== 行為正確比較
String比較引用equals() / Objects.equals()
Integer/Long 等比較引用 (-128~127 緩存除外)equals() / Objects.equals()
自定義類比較引用重寫 equals() + hashCode()

牢記:除基本類型外,業務邏輯比較「值」永遠用 equals() / Objects.equals()。

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