What's the point of creating both AbstractStringBuilder and StringBuilder?
Why didn't Java developers create one class AbstractStringBuilder
and rename it to StringBuilder
?
for example the method in AbstractStringBuilder
:
public AbstractStringBuilder append(double d) {
FloatingDecimal.appendTo(d,this);
return this;
}
and method in StringBuilder
:
@Override
public StringBuilder append(double d) {
super.append(d);
return this;
}
I suppose we can only store one method in AbstractStringBuilder
and it will work fine. What's the point in creating a useless shell StringBuilder
?
source to share
Since it is AbstractStringBuilder
not public class
, without asking the developers why they wrote it, one can only assume ...
Speculation
Please note that StringBuffer
,
Streaming, variable sequence of characters.
was added in 1.0. StringBuilder
Javadoc reads
Changed character sequence. This class provides an API that is compatible with
StringBuffer
but without the guarantee of synchronization. This class is intended to be used as a replacement for replacementsStringBuffer
in places where a string buffer was used by one thread (as is usually the case) . It is recommended that this class be used as a qualityStringBuffer
whenever possible, as it will be faster in most implementations.
(emphasis mine) and was added in 1.5. The idea is that in most cases this class is an improvement StringBuffer
, but in general it is very similar in functionality (can replace each other). As @immibis and @MadProgrammer point out in the comments, the idea of inheritance saves a ton of hassle in cases where you need similar functionality.
I found one simple example in the method append(String
). Into StringBuilder
this
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
Into StringBuffer
this
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
and in AbstractStringBuilder
this
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;
}
We can see that the only difference between thread-safe and non-thread-safe versions is some kind of cache control ( toStringCache
), but they both call the same method in their superclass, hence reuse code through inheritance.
Analogy
Think of it as you are one code. You are creating a class dog
that includes the anatomical structure of the dog (ears, tail, 4 legs ...) and methods related to its action, for example bark
. After 5 years, you want to create a class cat
to represent a cat. Will you start from scratch? No, you would create abstract class FourLeggedAnimal
with the structure of ears, tail, 4 legs, etc. And using the method makeSound
. Then you will continue this class and use all these similarities in both subclasses, overriding ( bark
and meow
) if necessary .
Requested
What's the point of creating a useless StringBuilder wrapper?
will be the same as someone asks you
What's the point in creating a useless Cat shell?
source to share