字符串池行为

Jax*_*xox 8 java string pool

我读了关于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)

Mir*_*ari 7

当你打电话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".

  • @ user2005443你通常不应该在每个字符串中添加`intern()`.那是不成熟的优化.如果你知道某些字符串(或通过分析找出)会被大量使用它可以帮助提高性能,但是如果你不加选择地使用它,它会[非常危险](http://www.codeinstructions. COM/2009/01 /破坏-javalangstringintern-myths.html). (5认同)
  • 虽然这个答案陈述了一个真实的事实,但它没有解释问题的*为什么*基础. (2认同)