在JDK 8中,StringBuffer
类具有toStringCache
,而StringBuilder
没有。
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
但为什么?
给定具有逃逸分析和偏向锁定功能的现代JVM,两者之间的区别是否还有意义?
最佳答案
考虑历史背景可能会有所帮助。 StringBuilder
是Java 5引入的,因为它已经被认识到,所以StringBuffer
不太适合其实际用例。
新引入的StringBuilder
是为在纯本地环境中构造,使用并随后立即删除的主要用例而设计的。因此,它不提供任何同步,也不会打扰优化其toString()
方法被多次调用而没有中间改变的罕见情况(这在现实生活中什么时候发生?),尤其是确实如此在不牺牲没有线程同步的性能优势的情况下提供缓存功能的过程介于“困难”到“不可能”之间。
虽然StringBuilder
被证明不是线程安全的,所以您知道并发调用其上的方法时可能会发生不一致的事情,但是String
类通过不可变性被保证是线程安全的,因此,切勿允许StringBuilder
不进行同步可能会导致已经构造的字符串不一致,并且根本不共享String
和StringBuilder
之间的数组是最安全的解决方案。
那么,如果在现实生活中几乎没有 yield ,为什么还要进行这种优化呢?好吧,因为它已经存在很长时间了,甚至很可能自Java 1.0以来就已经存在了,因此不值得更改StringBuffer
类中的任何内容。它的存在可能没有任何真正的优势,但是也没有删除它,这需要进行新的测试等等,并可能成为某些应用程序的space bar overheating feature。
您可能会注意到,然后在Java 1.x中做出了许多设计决定,这些决定今天看起来很奇怪。基本类中过度使用synchronized
就是其中之一,这对优化另一个类几乎没有帮助。那时,甚至连不变性的含义都没有被很好地理解,这就是为什么我们拥有像 String.valueOf(char[])
和 String.copyValueOf(char[])
这样的多余方法,以及使用 new String(char[])
的机会……