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

Java 字串連接與常量池:為什麼字面量拼接與變數拼接的 == 比較結果不同

     編輯:程式設計綜合問答

現象

String str1 = "aa", str2 = "bb";
String str3 = "aa" + "bb";        // 編譯期常量折疊 -> "aabb" 進入常量池
String str4 = str1 + str2;        // 執行期 StringBuilder -> 新物件
System.out.println(str3 == str4); // false

原理解析

  1. 編譯期常量折疊:"aa" + "bb" 在編譯時即計算為 "aabb",存入 字串常量池(String Constant Pool),str3 直接引用池中物件。
  2. 執行期字串連接:str1 + str2 編譯為 new StringBuilder().append(str1).append(str2).toString(),在堆上建立新 String 物件,str4 指向該物件。
  3. == 比較參考位址,故為 false。

驗證:查看位元碼

javap -c -verbose YourClass.class
// 會看到 str3 為 ldc #常量池索引,str4 為 StringBuilder 建構

最佳實踐

  • 比較字串內容**永遠使用 equals()**。
  • 需確保共用常量池物件時,呼叫 str4.intern() 將執行期物件放入/取得常量池引用。
  • 大量拼接使用 StringBuilder(非執行緒安全)或 StringBuffer(執行緒安全)。

圖解記憶體

常量池 (Perm/Metaspace)          堆
+------------------+              +------------------+
| "aabb"  <------- | str3         |                  |
+------------------+              | StringBuilder    |
                                  | .toString()      |
                                  | "aabb" <------- | str4
                                  +------------------+
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved