我读了关于Java的字符串池的这个问题 并理解了字符串池的基本概念,但仍然不理解这种行为.
第一:如果您直接分配值,则它可以工作,并且s1和s2都引用池中的同一对象
String s1 = "a" + "bc";
String s2 = "ab" + "c";
System.out.println("s1 == s2? " + (s1 == s2));
Run Code Online (Sandbox Code Playgroud)
但是如果我改变字符串s1 + ="d",那么池应该有一个字符串对象"abcd"?那么当我更改s2 + ="d"时,它应该在池中找到字符串对象"abcd",并将对象分配给s2?但它没有,它们不会被引用到同一个对象.这是为什么?
String s1 = "abc";
String s2 = "abc";
System.out.println("s1 == s2? " + (s1 == s2));
s1 += "d";
s2 += "d";
System.out.println("s1 == s2? " + (s1 == s2));
Run Code Online (Sandbox Code Playgroud)
当你打电话String.intern()给字符串时,保证字符串是合并的.
String s1 = "abcd".intern();
String s2 = "abc";
s2 += "d";
s2 = s2.intern();
s1 == s2 // returns true
Run Code Online (Sandbox Code Playgroud)
当编译器看到一个常量时,它足够智能来优化和汇集字符串文字,即:
String s1 = "abcd";
String s2 = "abcd";
s1 == s2 // returns true
Run Code Online (Sandbox Code Playgroud)
Java语言规范声明:
每个字符串文字都是类String(第4.3.3节)的实例(第4.3.1节,第12.5节)的引用(第4.3节).String对象具有常量值.字符串文字 - 或者更一般地说,作为常量表达式(第15.28节)的值的字符串 - 是"实例化"以便使用String.intern方法共享唯一实例.
所以在这种情况下s2 += "d",编译器并不像你那样聪明,只是汇集了"d".