thk*_*ala 8 java stringbuilder design-patterns stringbuffer
Java StringBuilder和StringBufferJava 之间的差异已经有很好的文档记录,并且在StackOverflow中也有所涉及.
基本上,StringBuilder是一个非同步副本StringBuffer,具有几乎相同的接口,因为它旨在作为更快速的替代品StringBuffer.它们的API实际上是相同的,它们实际上是当前JDK中相同的不可访问的抽象类的子类.
因此,我想知道的一件事就是它们与公众无关.让两个类实现一个公共接口或甚至StringBuffer作为子类都有StringBuilder意义,允许两个类共享代码的存在.
为什么这种被迫分离呢?是不是程序员不会无意中将线程安全与线程不安全的代码混合在一起?或者它只是一个设计疏忽,现在将继承到永恒的结束?
编辑:
为了说清楚:我可以推测为什么事情是这样的,但我希望具体参考实际的决定,例如在JSR过程中.对我来说,任何可能会对某些情况产生影响的事情偶然会引起一定程度的困难.
编辑2:
两个班级Appendable完全实现的事实让我大吃一惊.可能是因为该特定界面对于大多数目的而言是无用的 - 它只能附加单个字符或准备好的对象,就是这样.在大多数情况下,它并不比两个类都是子类更有用Object.
编辑3:
那么,以下是来自半官方来源的确切问题的基本原理:
图书馆团队评估:
根据设计,StringBuffer和StringBuilder不共享公共超类型.它们不是替代品:一个是错误(StringBuffer),另一个(StringBuilder)是它的替代品.
显然,在某些情况下,缺少常见的超类型会减慢从StringBuffer到StringBuilder的希望迁移.另一方面,通过添加一个共同的超类型,我们将把我们过去的错误带入公共界面并与我们永远保持一致.这不仅会减慢迁移速度:它会使迁移脱轨.
我没有 JSR 参考,但来自我的实验。以下是几个原因:
StringBuffer出于性能原因,作为 的子类StringBuilder 并不是一个好主意。为了确保StringBuffer线程安全,您必须屏蔽每个调用,StringBuilder这会产生大量开销。
添加到上面的一点,如果您可以直接访问类的内部,那么您可以进一步优化,java.lang.concurrent这就是 Java 在 api上添加的原因java.util.Collections.synchronized*。由于更直接的访问提供了更多的优化选项。支持这一点参考来自IBM博客
进一步补充第一点,我不认为这是一个设计疏忽,因为这两个类final绝对不希望这些类被子类化。
关于相同的接口,两个类都实现相同的接口,即Serializable, Appendable, CharSequence。所以它们是直接替代品。唯一的问题是它们没有实现一个通用接口,而是实现了三个通用接口。这是有道理的,因为不需要有一个臃肿的接口,从技术上讲,它是当前接口的总和(Serializable, Appendable, CharSequence)。
编辑:
StringBuffer,StringBuilder但不在任何已实现的接口中。这更多地与向后兼容性有关。您想要添加一个新的 api,但该接口正在被许多其他类使用,因此更改接口可能不可行。这是 Java 人员可能做出的一个经过深思熟虑的决定。所以我不会说这是一个错误。编辑2:
旁注:另一件事需要注意的是它StringBuffer是在 1.0 和StringBuilder1.5 中引入的。因此,两个类中都存在但接口中不存在的 api 是稍后引入的,而不是在创建这些类时引入的。