Java字符串和StringPool

时间:2009-12-14 19:55:54

标签: java string

public String makinStrings() {
   String m = "Fred47";
   String s = "Fred";
   s = s + "47";
   s = s.substring(0);
   return s.toString();
} 

代码创建了多少个对象?

我做了一个简单的测试:

public static void main(String[] args) {
   String m = "a";
   m += "bc";
   String s1 = "mabc".substring(1);
   String s2 = "abc";

   System.out.println(m == "abc");
   System.out.println(m == s1);
   System.out.println(m == s2);
   System.out.println(s1 == s2);
}

如果m,s1,s2指向同一个对象(“abc”),结果不应该是“true,true,true,true”吗? 相反,结果是“假,假,假,假”!

2 个答案:

答案 0 :(得分:5)

在这种情况下,结果为真 - 但ms1s2都引用不同的字符串。对于常量字符串表达式自动执行Interning,并且可以通过调用intern方法显式调用,但是字符串连接和子字符串不会自动发生。

在Sun的Java 7实现中,x.substring(0) 实际上会再次返回相同的引用(x),但我不相信这是由API保证的。< / p>

看一下你的例子:

public String makinStrings() {
   String m = "Fred47";
   String s = "Fred";
   s = s + "47";
   s = s.substring(0);
   return s.toString();
}

前两行要求内存中有两个字符串,但我不确切知道何时保证创建对象。一旦他们创建了,他们就会坚持下去 - 所以再次调用makinStrings将不再在这两行中创建。

字符串连接创建一个新的字符串对象。

substring调用将不会在我看过的实现中创建一个新的字符串对象 - 但它可以。

s.toString() 的调用不会创建一个新字符串(这在JavaDoc中指定)。

答案 1 :(得分:0)

不,只是因为两个字符串相等并不意味着它们的引用是相等的。

编译实例化一些字符串以节省空间,所以如果你尝试:

String s1 = "abc";
String s2 = "abc";

然后s1 == s2将为真,但这是一个特例,而不是一般规则。通常,在运行时生成的字符串默认情况下不共享相同的引用。