如何为StringBuffer(“”+“”+“”)完成内存分配

时间:2017-09-27 14:34:34

标签: java

String将始终创建新的内存空间,而StringBuffer则不会,只要我们附加新值,它就会更新现有的内存。

我的问题是:假设,我使用

new StringBuffer("A " + "B " + "C " + "D " + "E " + "F").toString();  

如何完成内存分配?

2 个答案:

答案 0 :(得分:1)

Java编译器足够聪明,可以在编译时连接String ABCDEF并将其加载为Compile time constant ..所以它只会在池中创建一个String。

答案 1 :(得分:1)

如果没有@Neerav描述的特殊情况优化(所以在较旧的JRE中,或者如果你没有文字字符串),你的代码最终会产生大量的CPU和内存开销。

你有"A " + "B " + "C " + "D " + "E " + "F"这个词。这转化为(没有优化)

new StringBuilder("A ").append("B ").append("C ").append("D ")
    .append("E ").append("F").toString()

执行代码行时,不会分配像"A "这样的文字字符串。在加载类时,它们会预先分配到字符串池中。

您的代码会创建一个StringBuilderStringBuffer的现代替代品)并将字符附加到其缓冲区。因此它分配StringBuilder基础对象加上一个字符数组。也许初始缓冲区不够大,然后在某些时候StringBuilder必须分配一个新的更大的数组,将字符从旧数组复制到新数组,然后继续。

最后,表达式必须是String而不是StringBuilder,因此您获得toString()。这将创建一个新的String基础对象以及一个具有完全正确大小的新字符数组。

然后将此表达式包装在new StringBuffer(...).toString()中,这是完全不必要的。首先,这将创建一个新的StringBuffer基础对象以及一个足够大的新字符数组,用于字符串并在那里复制字符。然后在此toString()上调用StringBuffer,这将创建另一个String基本实例和字符数组,并再次将字符复制到此新String对象中。您在String之前已经完全相同new StringBuffer(...).toString()

所以,你分配:

  • 1 StringBuilder
  • 2 Strings
  • 1 StringBuffer
  • 包括4个字符数组(如果StringBuilder的初始大小不够,可能更多)