字符串是不可变的 - 这意味着我永远不应该使用+ =而且只能使用StringBuffer?

cor*_*ath 11 java string stringbuilder stringbuffer immutability

字符串是不可变的,这意味着,一旦创建它们就无法更改.

那么,这是否意味着如果你用+ =附加的东西比你创建一个StringBuffer并附加文本那么需要更多的内存?

如果你使用+ =,每次必须保存在内存中时你会创建一个新的'对象',不是吗?

Jon*_*eet 25

是的,您每次都会使用+ =创建一个新对象.然而,这并不意味着它总是错误的做法.这取决于您是否希望将该值作为字符串,或者您是否只是使用它来进一步构建字符串.

如果您确实希望将结果x + y作为字符串,那么您也可以使用字符串连接.但是,如果你真的要(比方说)循环并附加另一个字符串,另一个字符串等 - 只需要将结果作为字符串放在最后,那么StringBuffer/StringBuilder就是你要走的路.实际上,循环实际上是StringBuilder在字符串连接中得到的回报 - 5个甚至10个直接连接的性能差异将非常小,但是对于数千个,它变得更糟 - 基本上因为你得到O(N 2)的复杂性串联与StringBuilder的O(N)复杂性.

在Java 5及更高版本中,你基本上应该使用StringBuilder - 它是不同步的,但这几乎总是可以的; 想要在线程之间共享一个是非常罕见的.

我有一篇关于所有这些你可能会觉得有用的文章.


Kyl*_*ndo 7

经验法则很简单:

如果您在循环中运行连接,请不要使用 +=

如果你没有在循环中运行连接,使用+=简单无关紧要.(除非性能关键应用程序


Kev*_*son 5

在Java 5或更高版本中,StringBuffer是线程安全的,因此除非您需要,否则您应该支付一些开销.StringBuilder具有相同的API,但不是线程安全的(即,您应该只在单个线程内部使用它).

是的,如果要构建大型字符串,则使用StringBuilder会更有效.作为API的一部分传递StringBuilder或StringBuffer可能是不值得的.这太令人困惑了.

  • StringBuffer一直是同步的 - 它们没有使它与Java 5同步,这就是他们引入StringBuilder的原因. (5认同)

Wer*_*sey 5

我同意上面发布的所有答案,但它会帮助您更多地了解Java的实现方式.JVM在内部使用StringBuffers来编译String +运算符(来自StringBuffer Javadoc):

编译器使用字符串缓冲区来实现二进制字符串连接运算符+.例如,代码:

     x = "a" + 4 + "c"
Run Code Online (Sandbox Code Playgroud)

被编译为相当于:

     x = new StringBuffer().append("a").append(4).append("c")
                           .toString()
Run Code Online (Sandbox Code Playgroud)

同样,x += "some new string"相当于x = x + "some new string".你知道我要去哪儿吗?

如果你正在进行大量的字符串连接,使用StringBuffer会提高你的性能,但是如果你只是做了几个简单的字符串连接,Java编译器可能会为你优化它,你不会注意到它的差别.性能