Why StringBuffer has a toStringCache while StringBuilder not?

无人久伴 提交于 2019-12-05 09:29:04

It might help to consider the historical context. StringBuilder was introduced with Java 5, since it has been recognized, that StringBuffer isn’t well suited for its actual use cases.

The newly introduced StringBuilder has been designed for the major use case of being constructed, used and immediately dropped afterwards, in a purely local context. Therefore, it doesn’t provide any synchronization and it doesn’t bother optimizing the rare case of its toString() method being called multiple times without an in-between change (when does this happen in real life at all?), especially as, indeed, providing the caching feature without sacrificing the performance advantage of no thread synchronization, is somewhere between “hard” to “impossible”.

While StringBuilder is documented to be not thread safe, so you know inconsistent things could happen when calling methods on it concurrently, the class String is guaranteed to be thread safe through immutability, hence, it must not be allowed that StringBuilder’s absence of synchronization can causes inconsistencies in already constructed strings and, not sharing the array between String and StringBuilder at all, is the safest solution.

So why is this optimization there, if it hardly ever has a benefit in real life? Well, because it’s there since a very long time, most likely even since Java 1.0 and it’s not worth changing anything in the class StringBuffer. Its presence may not have any real advantage, but neither has removing it, which would require new testing and so on and could turn out to be the space bar overheating feature for some application…

You may notice that back-then, in Java 1.x, a lot of design decision were made that may look strange today. Overusing synchronized in fundamental classes is one of them, this hardly ever helping optimization another one. At that time, even the implications of immutability were not well understood, which is why we have redundant methods like String.valueOf(char[]) and String.copyValueOf(char[]), plus the opportunity to use new String(char[])

I think that your first guess is highly accurate, since StringBuilder is not thread-safe and an instance can be shared across multiple threads, implementing such a cache would require additional synchronization, this would defeat the purpose of StringBuilder in the first place.

As to why this would be needed, it boils down to the new String(...) constructor that is used; in case of StringBuffer that used the constructor String(array, boolean) the comment says:

Package private constructor which shares value array for speed.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!