根据我的理解,字符串连接" +" 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?
答案 0 :(得分:4)
foo3 == foo1
返回true的原因是字符串池化。
当您连接字符串文字(甚至不是final
不是文字的字符串)时,连接在编译时发生,因此当程序执行值String foo1 = "foobar";
和String foo3 = "foobar";
时。
String pool或String table是堆上存储String引用的特殊区域。
现在,当您创建String foo1
时,如果没有其他值为foobar
的字符串文字,它将保留在池中。但是在foo3
的情况下,已经存在值为foobar
的字符串文字,因此foo1
和foo3
指向字符串池中的同一对象,这样做是为了节省内存。
使用new关键字创建String时,对象驻留在堆上,但不在String池之外。
如果您希望使用new关键字创建的字符串在String池中,如果池中已存在相同的值,则必须调用String intern()
方法并将该引用分配回String变量。
有关详情,请访问What is the Java string pool and how is “s” different from new String(“s”)?