4

Why did Java developers didn't create one class, AbstractStringBuilder and rename it to StringBuilder?

e.g., the method in AbstractStringBuilder:

public AbstractStringBuilder append(double d) { FloatingDecimal.appendTo(d,this); return this; } 

and the method in StringBuilder:

@Override public StringBuilder append(double d) { super.append(d); return this; } 

I suppose we can keep only one method in AbstractStringBuilder and it will work fine. What's the point of creating the useless wrapper StringBuilder?

3
  • Short answer: So StringBuffer could extend it, too. Commented May 4, 2015 at 21:18
  • 1
    Abstract classes are generally created to provide a base from which other implementations can extend from without the need to provide a lot of boiler plate or duplicated code. It's possible the the append(double) method in StringBuilder was implemented different to begin with and was changed over time Commented May 4, 2015 at 21:21
  • 4
    AFAIK, StringBuffer came first, and then they wanted to add StringBuilder. So they probably moved all the code from StringBuffer into AbstractStringBuilder, then made it extend it, and then made StringBuilder extend it too. Commented May 4, 2015 at 21:31

1 Answer 1

5

Since AbstractStringBuilder is not a public class, short of asking the developers why they wrote it, one can only speculate...

Speculation

Note that StringBuffer,

A thread-safe, mutable sequence of characters.

was added in 1.0. StringBuilder's Javadoc reads

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

(emphasis mine) and was added in 1.5. The idea is that this class is an improvement upon StringBuffer in most cases, but is overall very similar in functionality (can replace each other). As noted by @immibis and @MadProgrammer in the comments, the idea of inheritance saves a lot of trouble in cases where you want similar functionality.

I found one simple example in the method append(String). In StringBuilder, it is

@Override public StringBuilder append(String str) { super.append(str); return this; } 

In StringBuffer it is

@Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } 

and in AbstractStringBuilder it is

public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } 

What we see is that the only difference between the thread-safe and not thread-safe versions is some cache control (toStringCache), but they both call the same method in their superclass, hence reusing code through inheritance.

Analogy

Think of it as if you are the one writing code. You create a class dog which includes the anatomical structure of a dog (ears, tail, 4 legs...) and methods related to its action, like bark. After 5 years you want to create a class cat to represent a cat. Would you start from scratch? No, you would create an abstract class FourLeggedAnimal with the structure of ears, tail, 4 legs etc., and with the method makeSound. You will then extends this class and use all those similarities in both subclasses, overriding when necessary (bark and meow).

Asking

What's the point of creating the useless wrapper StringBuilder?

will be the same as someone asking you

What's the point of creating the useless wrapper Cat?

Sign up to request clarification or add additional context in comments.

2 Comments

The key idea in that very-good answer is ... "after five years you now want to." (And, you want to do it without breaking tons of existing code and/or forcing all of it to be re-validated. You didn't write the original code. The guy who did got smooshed by a bread-truck. You have very little time in which to get this done reliably.) The abstract-class didn't previously exist, because it wasn't necessary. Adding it, specifically as a junction-point for implementing cat, is a very safe way to graft-on the new functionality in such (legacy ...) programs.
@MikeRobinson Very true, although even if you did write the original class and you have a lot of time, it would still be the right approach (or at least a right approach). It is not always the case though in other JDK areas, unfortunately.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.