字符串对象计数SCJP

时间:2015-02-24 11:44:02

标签: java string

另一个让我困惑的考试题目:

public String makinStrings() {
 String s = “Fred”;
 s = s + “47”;
 s = s.substring(2, 5);
 s = s.toUpperCase();
 return s.toString();
}

问题是: "调用此方法时将创建多少个String对象?"

正确答案应该是3但我更重要的是:
弗雷德
47个
Fred47
ED4
ED4

3真的是正确答案吗?如果是这样 - 为什么?

2 个答案:

答案 0 :(得分:1)

在实例化类时实例化字符串常量。正因为如此,字符串" Fred"和" 47"在调用方法之前实例化,而不是在方法调用期间实例化。

本文解释了它:The String Constant Pool

但我会稍微改进一下:Java虚拟机规范指定常量" Fred"和" 47"作为字符串常量池中的条目放置。 (java SE specs, loading and linking)。

加载类时会发生

要关注的另一点:问题是实例化了多少个对象

所以,

String s =" Fred" :没有实例化一个新的String对象,只使用内化的" Fred"恒定。

s = s +" 47" :' +'运算符意味着连接操作;该连接的结果是一个新的String对象。因此,1 String实例化。 " 47"载满了班级......

s = s.substring(2,5):方法定义指定必须返回一个新的字符串对象(String.substring javadoc),因此,2个字符串被实例化。

即使实现(例如the openJDK java.lang.String implementation)可能使用某种构造函数来仅引用具有String内部值的字符数组的一部分,结果一个新的String,即使是一种"懒惰的"之一。

s = s.toUpperCase():同样在这里,toUpperCase方法必须返回一个新的String。所以,3 Strings实例化了。

最后, s.toString()将对象的表示形式返回为String。由于String 已经是一个String,s.toString()只返回完全相同的String对象......

答案 1 :(得分:0)

3个对象:
弗雷德 Fred47
ED4

 s = s + “47”;

47将不会在字符串池

上创建
s = s.substring(2, 5);

不应创建单独的字符串,而是遵循flyweight模式并在内部指向相同的字符串。