为什么StringBuffer有一个toStringCache而StringBuilder没有?

nty*_*sdd 6 java stringbuilder stringbuffer java-8

在JDK 8中,StringBuffer类有一个toStringCache,而StringBuilder没有.

/**
 * A cache of the last value returned by toString. Cleared
 * whenever the StringBuffer is modified.
 */
private transient char[] toStringCache;
Run Code Online (Sandbox Code Playgroud)

但为什么?

  • 我能想到的一个可能原因是StringBuffer已经同步,因此可以更容易地实现缓存.

  • 或者也许历史上StringBuffer是以这种方式实现的,所以旧代码在很大程度上依赖于这个功能?

鉴于具有逃逸分析和偏向锁定的现代JVM,差异是否相关?

Hol*_*ger 6

考虑历史背景可能有所帮助.StringBuilderJava 5引入,因为它已经被认识到,它StringBuffer不适合它的实际用例.

新引入的StringBuilder设计用于在纯粹的本地环境中构建,使用和立即丢弃的主要用例.因此,它不提供任何同步,并且它不会打扰优化其toString()方法被多次调用的罕见情况而没有中间变化(这在现实生活中何时发生?),特别是,实际上,提供缓存功能而不牺牲无线程同步的性能优势,介于"硬"到"不可能"之间.

虽然StringBuilder记录为不是线程安全的,但是你知道在同时调用方法时可能会发生不一致的事情,String通过不变性保证类是线程安全的,因此,不能允许StringBuilder缺少同步会导致不一致在已经构造的字符串和,不共享之间的阵列StringStringBuilder在所有,是最安全的解决方案.

那么为什么这种优化在那里,如果它在现实生活中几乎没有任何好处呢?好吧,因为它存在很长一段时间以来,很可能甚至从Java 1.0开始,它不值得改变课堂上的任何东西StringBuffer.它的存在可能没有任何真正的优势,但也没有删除它,这将需要新的测试等等,并可能成为某些应用程序的空格键过热功能 ...

您可能会注意到,在Java 1.x中,很多设计决策在今天看起来很奇怪.synchronized在基础课中过度使用是其中之一,这几乎没有帮助优化另一个.当时,即使是不可变性的影响也没有得到很好的理解,这就是为什么我们有多余的方法,比如String.valueOf(char[])String.copyValueOf(char[]),以及使用机会new String(char[])...

  • @ntysdd(和@Holger)当然`copyValueOf`方法无关紧要.在历史记录中,JDK 1.0之前,`String(char [])`构造函数和`valueOf(char [])`方法(都是public)只是将参数的引用存储在新构造的字符串中.当然,这导致了可变的字符串!添加`copyValueOf`方法来复制数组,然后修改构造函数和`valueOf`以制作副本,使`copyValueOf`方法变得多余.但是,它们从未被清理过. (2认同)