In the book "Effective Java", Josh Bloch says that
StringBuffer is largely obsolete and should be replaced by the non-synchronized implementation 'StringBuilder'
.
But in my experience, I've still seen widespread use of th开发者_如何学运维e StringBuffer class. Why is the StringBuffer class now obsolete and why should StringBuilder be preferred over StringBuffer except for the increased performance due to non-synchronization?
It's obsolete in that new code on Java 1.5 should generally use StringBuilder
- it's very rare that you really need to build strings in a thread-safe manner, so why pay the synchronization cost?
I suspect code that you see using StringBuffer
mostly falls into buckets of:
- Written before Java 1.5
- Written to maintain compatibility with older JDKs
- Written by people who don't know about
StringBuilder
- Autogenerated by tools which don't know about
StringBuilder
Not everyone reads as widely as you :-)
I'm only half-joking. People copy code and patterns all the time. Many people don't stay in touch with API changes.
Why is StringBuffer obsolete? Because in the vast majority of cases, its synchronised behaviour isn't required. I can't think of a time I've ever needed it. Despite the fact that synchronisation is not now the performance issue it once was, it makes little sense to pay that tax in scenarios where it's unnecessary.
Why is the StringBuffer class now obsolete?
Because its operations are synchronized, which adds overhead and is rarely useful.
The reason why you still see StringBuffer
used widely is simply inertia: There are still countless code examples tutorials out there that were never updated to use StringBuilder
, and people still learn outdated practices (not just this one) from such sources. And even people who know better often fall back to old habits.
I think obsolete is an overstatement.
StringBuffer is synchronized. StringBuilder is not.
In many (maybe most) cases, you won't care about the thread safety of something used to build strings. You should use StringBuilder in these cases. In some cases, however, you may very well want to make sure actions on the object is thread safe. StringBuffer is still useful in those cases.
Not only is synchronisation not required in most cases, it actually gives readers of your code wrong information if you nevertheless use it: namely, the reader could be led to believe that synchronisation is required where it actually isn’t.
Using a StringBuilder
instead advertises the fact that you don’t expect cross-thread access.
In fact, sending data across threads should almost always be done through well-defined channels of communication anyway, not simply by accessing a synchronised string buffer. So in a way I would recommend always using a different solution, even when a StringBuffer
seems appropriate at first glance.
精彩评论