关于" +"运算符及其StringBuilder实现

时间:2016-10-06 07:06:17

标签: java string stringbuilder string-concatenation

根据我的理解,字符串连接" +" Java中的operator是使用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方法internall调用" new String" ,所以不应该像foo2一样foo3?

1 个答案:

答案 0 :(得分:4)

foo3 == foo1返回true的原因是字符串池化。

当您连接字符串文字(甚至不是final不是文字的字符串)时,连接在编译时发生,因此当程序执行值String foo1 = "foobar";String foo3 = "foobar";时。

String pool或String table是堆上存储String引用的特殊区域。

现在,当您创建String foo1时,如果没有其他值为foobar的字符串文字,它将保留在池中。但是在foo3的情况下,已经存在值为foobar的字符串文字,因此foo1foo3指向字符串池中的同一对象,这样做是为了节省内存。

使用new关键字创建String时,对象驻留在堆上,但不在String池之外。

如果您希望使用new关键字创建的字符串在String池中,如果池中已存在相同的值,则必须调用String intern()方法并将该引用分配回String变量。

有关详情,请访问What is the Java string pool and how is “s” different from new String(“s”)?