据我了解,Java中的字符串连接“+”运算符是使用Stringbuilder实现的,例如:
String s = "foo" + "bar"
内部编译为:
String s = new StringBuilder().append("foo").append("bar").toString();
所以我尝试了这样的事情:
String foo1 = "foobar";
String foo2 = new String("foobar");
String foo3 = "foo" + "bar";
char[] fooarray = {'f','o','o','b','a','r'};
String foo4 = new String(fooarray);
接下来我使用 == 运算符对它们进行了相互测试。结果基本上符合我的预期:foo2 和 foo4 没有为任何其他字符串返回“==”。
但是,foo3 == foo1 返回 true。这是什么原因呢? StringBuilder 类的 toString 方法内部调用“new String”,因此 foo3 不应该是一个唯一的对象,就像 foo2 一样吗?
最佳答案
foo3 == foo1
返回true的原因是字符串池的原因。
当您连接字符串文字(甚至不是文字的 final
字符串)时,连接会在编译时发生,因此当程序执行值时 String foo1 = "foobar";
和 String foo3 = "foobar";
。
字符串池或字符串表是堆上存储字符串引用的特殊区域。
现在,当您创建字符串 foo1
时,如果没有其他值为 foobar
的字符串文字,它将保留在池中。但在 foo3
的情况下,已经有一个值为 foobar
的字符串文字,因此 foo1
和 foo3
指向同一个对象在字符串池中,这样做是为了节省内存。
当您使用 new 关键字创建字符串时,该对象驻留在堆上,但位于字符串池之外。
如果您希望使用 new 关键字创建的字符串位于字符串池中,并且池中已存在相同的值,则必须调用 String intern()
方法并将引用分配回字符串变量。
了解更多信息 - What is the Java string pool and how is “s” different from new String(“s”)?
关于java - 关于 "+"运算符及其 StringBuilder 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39889608/