public class TestStringEquals {
public static void main(String[] args) {
String a = "test";
String b = "test";
String c = new String("test");
String d = new String("test");
String e = a;
String f = new String(a);
String g = a + "";
System.out.println(a == b); // true
System.out.println(a == c); // false
System.out.println(c == d); // false
System.out.println(a == e); // true
System.out.println(a == f); // false
System.out.println(a == g); // false
if (a.equals(b) && b.equals(c) && c.equals(d) && d.equals(e)
&& e.equals(f) && f.equals(g)) {
System.out.println("所有 equals 比較均為 true");
}
}
}
a == b 為 true:字面量 "test" 編譯期進入字符串常量池,a 和 b 指向同一池對象。new String("test") 每次在堆中創建新對象,故 c、d、f 地址各不相同。a + "" 因字符串拼接運算符重載,內部會 new StringBuilder().append(...).toString(),產生新堆對象,故 g 地址不同。e = a 直接賦值引用,故 a == e 為 true。String 重寫了 Object.equals(),逐字符比較值。因此所有變量 equals 比較均返回 true。
String s = "abc")會檢查常量池,存在則復用,不存在則創建並入池。new String("abc") 強制在堆創建新對象,不入池(除非調用 intern())。equals() 或 equalsIgnoreCase()。==。new String() 或拼接,優先用 StringBuilder。