== vs equals() 核心差異| 運算子 | 比較內容 | 典型結果 |
|---|---|---|
== | 參考位址(記憶體地址) | 同一物件才為 true |
equals() | 字元序列內容 | 內容相同即為 true |
== 也會是 true?Java 編譯器將字串字面常量(如 "abc")放入字串常量池,相同內容只會有一份物件。因此:
String a = "hello";
String b = "hello";
System.out.println(a == b); // true(指向常量池同一物件)
== 會失效?String c = new String("hello"); // 強制在堆區建立新物件
String d = "hello";
System.out.println(c == d); // false(不同物件)
System.out.println(c.equals(d)); // true(內容相同)
String e = "hel" + "lo"; // 編譯期常量折疊 → 常量池
String f = "hello";
System.out.println(e == f); // true
String g = "hel";
String h = g + "lo"; // 運行期 new StringBuilder → 堆區新物件
System.out.println(h == f); // false
str.equals("abc") vs "abc".equals(str)| 寫法 | 優點 | 缺點 | 建議 |
|---|---|---|---|
str.equals("abc") | 符合閱讀習慣 | 需先判 str != null,否則拋 NPE | 需加非空檢查 |
"abc".equals(str) | Null-safe,常量不為 null | 稍違直覺 | 推薦 |
null 陷阱String a = null, b = null, c = "呵呵";
System.out.println(a + b + c); // 輸出:"nullnull呵呵"
原因:StringBuilder.append(null) 會附加字串 "null"。實務上請使用 Objects.toString(obj, "") 或 String.valueOf(obj) 避免「null」字樣混入業務資料。
equals()(或 Objects.equals())"expected".equals(actual)String val = (str == null) ? "" : str;StringBuilder,避免產生大量中間物件new String()、StringBuilder、+ 運算子的物件建立差異intern() 手動入池String s = new String("hello").intern(); // 從常量池取得/放入同樣內容的參考
System.out.println(s == "hello"); // true
慎用:過度 intern() 會擴大常量池(永久代/Metaspace),影響 GC。