在此字符串操作期间将创建多少个对象?

时间:2012-07-26 16:15:35

标签: java

以下是实例方法

中的代码段
 String x = new StringBuffer().append("a").append("b").append("c").toString()

我受到印象,首先创建一个新的stringbuffer,然后在字符串缓冲区的附近添加一个, 类似的b和c。之后,将stringbuffer转换为字符串。因此,就我而言,创建了2个对象(一个用于字符串缓冲区,另一个用于字符串)。 正确?基本上,就我而言,不会为字符串“a”,“b”,“c”创建中间对象。这是对的吗?

编辑: - 根据所有回复,看起来会为字符串文字“a”,“b”,“c”创建对象但是如果我通过链接http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/StringBuffer.html#toString(),这不应该创建临时字符串。搜索“总的来说,这可以避免创建许多临时字符串。”在这个链接上。同意它适用于1.4.2,但我希望基本保持相同的1.6

是的,如果我在下面而不是超过五个对象将被创建。三个为“a”,“b”,“c”。一个字符串缓冲区。然后最后为从中转换的字符串 StringBuffer的。对于“a”,“b”,“c”以及最后一个字符串“abc”的对象将太过游泳并且终生存在

String str1="a";
String str2="b";
String str3="c";
String x = new StringBuffer().append(str1).append(str2).append(str3).toString()

以上理解是否正确?

3 个答案:

答案 0 :(得分:3)

根据创建的对象数量,第一个和第二个代码段之间没有区别。字符串"a""b""c"将参与此过程,但可以使用 interned 副本。如果没有对str1..str3的进一步引用,编译器可以自由地将第二个片段转换为第一个片段,从而消除变量。

此外,如果内部字符串中的内存不足以保存附加的数据,则StringBuffer的{​​{1}}内可能会有内部重新分配。这只是理论上的可能性,但它就在那里。

答案 1 :(得分:1)

正如其他答案中所指出的,您的两个片段是等效的(关于String对象创建)。如果第二个片段写成:

,则会有所不同
String str1= new String("a");
...

只有在这种情况下,您才能保证实例化一个新的String对象(而不是您通常想要的那个)。另请参阅here

答案 2 :(得分:1)

字符串“a”,“b”,“c”在您的代码片段中都是文字。它们将在代码执行之前由类加载器创建,并且没有办法(通常也没有任何意义)可以避免这种情况。

因此,两个代码片段基本上都是相同的,并且它们都创建了相同数量的对象。

而且,BTW这两个片段都不是有效代码 - 您不能像在两个片段中的最后一个语句中那样分配StringBuffer = String。

编辑:你也问过Java版本> 1.4。从Java5开始,StringBuffer应该用StringBuilder替换(它基本上完全相同,但它不同步,因此它执行得更好)。