在 JDK 8 中,StringBuffer
类有一个toStringCache
, while StringBuilder
没有。
/**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache;
But why?
考虑到现代 JVM 具有逃逸分析和偏向锁定,这种差异还有意义吗?
考虑历史背景可能会有所帮助。StringBuilder
是随 Java 5 一起引入的,因为人们已经认识到,StringBuffer
不太适合其实际用例。
新推出的StringBuilder
专为在纯粹的本地环境中构建、使用并随后立即丢弃的主要用例而设计。因此,它不提供任何同步,也不会费心优化其罕见的情况toString()
方法被多次调用而没有中间变化(这种情况在现实生活中什么时候发生?),特别是事实上,在不牺牲无线程同步的性能优势的情况下提供缓存功能,是介于“困难”和“困难”之间的。 “不可能的”。
While StringBuilder
被记录为不是线程安全的,所以你知道在并发调用它的方法时可能会发生不一致的事情,该类String
通过不变性保证线程安全,因此,决不允许StringBuilder
缺乏同步可能会导致已构造的字符串不一致,并且不共享数组String
and StringBuilder
无论如何,这是最安全的解决方案。
既然这种优化在现实生活中几乎没有任何好处,那么为什么还要进行这种优化呢?嗯,因为它已经存在很长时间了,很可能甚至从 Java 1.0 开始,并且不值得更改类中的任何内容StringBuffer
。它的存在可能没有任何真正的优势,但删除它也没有任何好处,这需要新的测试等,并且可能会成为空格键过热功能 https://xkcd.com/1172/对于某些应用程序...
您可能会注意到,当时在 Java 1.x 中做出的许多设计决策在今天看来可能很奇怪。过度使用synchronized
基础类就是其中之一,这几乎无法帮助优化另一类。当时,甚至连不变性的含义也没有得到很好的理解,这就是为什么我们有像这样的冗余方法String.valueOf(char[]) https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#valueOf-char:A- and String.copyValueOf(char[]) https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#copyValueOf-char:A-,加上使用的机会new String(char[]) https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#String-char:A-…
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)