51

Josh Bloch 在《Effective Java》一书中说

StringBuffer 在很大程度上已过时,应由非同步实现“StringBuilder”取代

.

但根据我的经验,我仍然看到 StringBuffer 类的广泛使用。为什么 StringBuffer 类现在已经过时了,为什么 StringBuilder 比 StringBuffer 更受欢迎,除了由于非同步而提高的性能?

4

5 回答 5

71

Java 1.5 上的新代码通常应该使用它已经过时了StringBuilder——你真的需要以线程安全的方式构建字符串是非常罕见的,那么为什么要支付同步成本呢?

我怀疑您看到的代码StringBuffer主要属于以下类别:

  • 在 Java 1.5 之前编写
  • 为保持与旧 JDK 的兼容性而编写
  • 不知道的人写的StringBuilder
  • 由不知道的工具自动生成StringBuilder
于 2011-07-21T11:08:17.503 回答
19

不是每个人都像你一样广泛阅读:-)

我只是半开玩笑。人们一直在复制代码和模式。许多人不会与 API 更改保持联系。

为什么 StringBuffer 过时了?因为在绝大多数情况下,它的同步行为不是必需的。我想不出我曾经需要它的时间。尽管同步现在不再是曾经的性能问题,但在不必要的情况下支付该税是没有意义的。

于 2011-07-21T11:05:51.110 回答
9

为什么 StringBuffer 类现在已经过时了?

因为它的操作是同步的,这增加了开销并且很少有用。

您仍然看到被广泛使用的原因StringBuffer只是惯性:仍然有无数的代码示例教程从未更新为使用StringBuilder,人们仍然从这些来源学习过时的实践(不仅仅是这个)。即使是更了解的人也经常回到旧习惯。

于 2011-07-21T11:10:43.560 回答
5

我认为过时是夸大其词。

StringBuffer 是同步的。StringBuilder 不是。

在许多(也许是大多数)情况下,您不会关心用于构建字符串的线程安全性。在这些情况下,您应该使用 StringBuilder。然而,在某些情况下,您可能非常希望确保对对象的操作是线程安全的。StringBuffer 在这些情况下仍然有用。

于 2011-07-21T17:06:22.593 回答
4

不仅在大多数情况下不需要同步,而且如果您仍然使用它,它实际上会给阅读您的代码的读者提供错误信息:也就是说,可能会导致读者相信在实际上不需要同步的情况下需要同步。

使用 aStringBuilder来代替宣传您不期望跨线程访问的事实。

事实上,跨线程发送数据几乎总是应该通过定义良好的通信通道来完成,而不是简单地通过访问同步的字符串缓冲区。因此,在某种程度上,我建议始终使用不同的解决方案,即使StringBuffer乍一看似乎合适。

于 2011-07-21T14:13:48.193 回答