Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of creating both AbstractStringBuilder and StringBuilder?

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?

like image 449
Dmitry1405 Avatar asked Oct 24 '25 18:10

Dmitry1405


1 Answers

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?

like image 81
user1803551 Avatar answered Oct 26 '25 08:10

user1803551



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!