2012-03-19 53 views
8

Java中的StringBuilderStringBuffer之间的差异已有详细记录,并且也是touched upon in StackOverflow为什么不让StringBuilder和StringBuffer实现一个通用接口?

基本上,StringBuilderStringBuffer的非同步副本,它具有几乎相同的接口,因为它旨在作为StringBuffer的更快捷的替代替代方案。他们的API实际上是相同的,他们实际上是在当前JDK中抽象类相同的不可访问的的子类。

我想知道的一件事就是为什么他们不是公开相关。让这两个类实现一个通用接口,或者甚至将StringBuffer作为StringBuilder的子类是合理的,从而允许两个类都存在共享代码。

那么为什么这个强制分离呢?这是否让程序员不会无意中将线程安全和线程不安全的代码混合在一起?还是仅仅是一种设计监督,现在会被遗传到永恒的尽头?

编辑:

为了把事情说清楚:我可以为什么事情都是这样猜测,但我希望能具体引用到实际的决策,例如在JSR过程中。任何能够说明对我而言是什么的情况都会偶尔造成一定的困难。

编辑2:

两个类都实现Appendable事实完全忘了。可能是因为该特定界面在大多数情况下都没有用处 - 它只能追加一个字符或一个准备好的对象,就是这样。在大多数情况下,这两个类都不是Object的子类。

编辑3:

嗯,这里是正是这个问题从a semi-official source的理由:由图书馆团队

评价:

它是由设计的StringBuffer和StringBuilder的没有共同的 公共超类型。他们不打算成为替代品:一个是 错误(StringBuffer),另一个(StringBuilder)是其替代品 。

很明显,在某些情况下,缺少常见的超类型会减缓从StringBuffer到StringBuilder的希望迁移。另一方面 就是通过添加一个常见的超类型,我们会将过去的错误记录下来,并将它们放入一个公共接口中,以便与我们联系所有的 时间。这不仅会减缓迁移速度,而且会导致迁移。

回答

3

我没有JSR参考,但从我的exp。下面是几个方面的原因:

  • StringBuffer子类的StringBuilder没有因为性能原因一个好主意。为了使StringBuffer线程安全,您必须掩盖每个致电StringBuilder的呼叫,这是很大的开销。

  • 添加到上述点,可以进一步优化,如果你有超过一类的内部,这就是为什么Java的加入java.lang.concurrent超过java.util.Collections.synchronized*的API的原因直接访问。随着更多直接访问提供更多优化选项。要询问服务这一点Reference from the IBM blog

  • 进一步增加了第一点,我认为这是一个设计监督作为两个类都final所以肯定他们不希望被继承这些类。

  • 关于相同的接口,两个类实现相同的接口,即Serializable, Appendable, CharSequence。所以他们是直接替换。唯一的问题是它们没有实现一个通用接口,而是实现了三个通用接口。这是有道理的,因为不需要有一个技术上会成为当前接口总和的臃肿接口(Serializable, Appendable, CharSequence)。

编辑:

  • 为了@MatthewFlaschen点,有蜜蜂它们是相同的B/W StringBufferStringBuilder但不是在任何实现的接口。这更多的是与向后兼容。你想添加一个新的API,但接口正在被许多其他类使用,所以改变一个接口可能是不可行的。这是Java人员可能做出的一个深思熟虑的决定。所以我不会说它是一个错误。

编辑2:

边注:另外要注意的是,StringBuffer在1.0和1.5 StringBuilder介绍。所以在两个类中都有,但不在接口中的apis稍后会介绍,而不是在创建这些类时。

+0

有一些方法,例如附加(长)在两个类中,但没有接口。 – 2012-03-19 03:45:37

+0

虽然我想像Vector和ArrayList扩展AbstractList,但StringBuffer和StringBuilder可以扩展一个类似的抽象类。我没有看到最新的源代码,但StringBuilder似乎是一个直接的StringBuffer减去同步。 – 2012-03-19 03:48:27

+0

@MatthewFlaschen append()来自Appendable。 – 2012-03-19 03:49:42

2

他们实际上都做了Appendable

我不认为这是无用的。根据我的经验,StringBuilder/StringBuffer用法的很大一部分只是处理字符串(实现CharSequence)。对于其余的,您可以在通过之前调用String.valueOf

如果有另一个接口也有其他方法,如append(long),那将很方便。但这不是必需的。

具有通用接口是合理的。它们具有不同的性能和线程特性,但这对于JDK中的许多接口来说都很好并且真实。

例如,CopyOnWriteArrayList在基于阵列的线程安全列表(它使每写一个新的列表),而LinkedList是一个非线程安全的链表。

+0

你没有回答这个问题,或者甚至不明白为什么会这样。 – FriendlyGuy 2012-03-19 03:17:07

+0

@MackieChan,我不同意。我说过“拥有共同的界面是合理的”,这是另一种说法:“是的,这是一种设计监督”。 – 2012-03-19 03:18:21

+0

老实说,Appendable滑倒了我的想法,主要是因为我经常追加数字e.t.c.在我的代码中。我没有真正发现那个特殊的界面非常有用,因为它强制你事先将所有的东西都转换成字符串。更不用说现有的内容是不可改变的... – thkala 2012-03-19 03:29:55

相关问题