为什么StringBuilder是final的 - 而不是拥有全部final方法?

8
这个想法的动机是我对早期关于StringBuilder最佳实践的问题的回答("一厢情愿的想法")。如果StringBuilder是可扩展的,那么特定于领域的子类可以扩展其流畅接口,这样就可以紧凑代码,其中一个StringBuilder被传递给许多方法来构建更大的字符串的部分。
我在考虑建议一些东西 - 也许是一个StringBuilder代理 - 给Guava的人们。
StringBuilder是final而不是只有final方法,它还有什么额外的目的呢?

我认为委托是正确的方式。 - JustinKSU
1个回答

10
如果所有方法都是final的话,则无法修改StringBuilder的当前行为。 它的子类必须添加未连接的行为(这在本质上是不好的设计),或者添加使用旧行为的新功能,例如方便方法。 如果您想做后者,最好拥有一个提供相关功能但包含StringBuilder的类,而不是扩展它。 正如Joshua Bloch所说,“优先使用包容性而非继承性”。 简而言之,如果所有方法都是final的,没有很好的理由来扩展该类,因此您可能要将其也设置为final。

2
你肯定不想在每个子类中委托 StringBuilder 的所有方法,而子类绝对需要访问其中很多方法,以便执行诸如 builder.appendMyBeginning().append('.').appendMyEnd() 这样的操作。因此实际上,您是建议使用具有相同一组方法的通用委托,然后再进行子类化吗? - Ed Staub
可以这样做。我认为特定的 StringBuilder 使用可能不需要所有 StringBuilder 的方法。您可以实现并委托您需要的那些方法,并添加任何额外的方法。 - DJClayworth
正如Joshua Bloch所说,“避免创建不必要的对象” ;) 总的来说,我认为AbstractStringBuilderAppendablePrintWriterWriterPrintStreamOutputStream这整个东西都是一个糟糕设计的例子。很明显,它们都必须共享一些通用的更广泛的接口,以便以统一的方式附加各种原始类型。... - actual
相反,AppendableWriterOutputStream的实现分化成了无数个专业化的实现,都在做同样的事情。将长整型值附加到StringBuilder和将其写入PrintWriterPrintStream之间有什么区别?这只是一个修辞问题。如果需要同时支持字符串构建器、写入器和流,那就是一场噩梦,这完全是关于包装器的包装器。没有冒犯之意,只是抱怨 :) - actual
1
我不同意。例如,我只想添加一个appendLine()方法,它与append完全相同,但如果已经存在内容,则添加换行符分隔符。这不是无关行为,我也不想改变任何现有方法的行为。必须为所有现有方法复制传递方法以创建容器,这非常痛苦。 - BobDoolittle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接