创建AbstractStringBuilder和StringBuilder有什么意义?

4
为什么Java开发者没有创建一个名为StringBuilder的类,并将其重命名为AbstractStringBuilder?例如,在AbstractStringBuilder中的方法:
public AbstractStringBuilder append(double d) {
    FloatingDecimal.appendTo(d,this);
    return this;
}

还有在StringBuilder中使用的方法:

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

我觉得我们可以只保留AbstractStringBuilder中的一种方法,这样就可以很好地工作。创建无用的包装器StringBuilder有什么意义呢?


简短回答:所以 StringBuffer 也可以扩展它。 - Louis Wasserman
1
抽象类通常被创建为提供一个基础,其他实现可以从中扩展而无需提供大量样板或重复代码。可能StringBuilder中的append(double)方法最初是以不同的方式实现的,并随时间改变了。 - MadProgrammer
4
据我所知,StringBuffer先出现了,然后他们想要添加StringBuilder。因此,他们可能将所有的代码从StringBuffer移动到了AbstractStringBuilder中,然后让StringBuffer继承它,并且让StringBuilder也继承它。 - user253751
1个回答

5
由于AbstractStringBuilder不是一个公共类,除了向开发人员询问他们为什么编写它之外,只能进行推测...
推测:
请注意,StringBuffer是1.0版本中新增的

一个线程安全,可变的字符序列。

StringBuilder的Javadoc如下:

一个可变的字符序列。此类提供了与StringBuffer兼容的API,但并不保证同步。这个类被设计成可以在单线程情况下作为StringBuffer的一种替换使用,因为这通常是情况)。在可能的情况下,建议优先使用这个类代替StringBuffer,因为在大多数实现下速度更快。

(重点在于“这个类被设计成可以在单线程情况下作为StringBuffer的一种替换使用,因为这通常是情况”)且是在1.5中新增的。该类在大多数情况下都是StringBuffer的改进版,但在功能上非常相似(可以互换)。正如评论中@immibis和@MadProgrammer所指出的那样,继承的思想在希望获得类似功能的情况下可以节省很多麻烦。
我在append(String)方法中找到了一个简单的例子。在StringBuilder中,代码如下:
@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

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

AbstractStringBuilder中,它是这样的。
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;
}

我们可以看到,线程安全和非线程安全版本之间唯一的区别是一些缓存控制(toStringCache),但它们都调用其超类中的相同方法,因此通过继承重用代码。
比喻
想象一下,如果您正在编写代码。您创建了一个名为dog的类,其中包括狗的解剖结构(耳朵、尾巴、4条腿等)和与其行动相关的方法,如bark。5年后,您想创建一个代表猫的类cat。你会从头开始吗?不,您将创建一个抽象类FourLeggedAnimal,其中包含耳朵、尾巴、4条腿等结构,并具有makeSound方法。然后您将扩展此类并在两个子类中使用所有这些相似之处,在必要时进行覆盖(barkmeow)。
问答
询问

创建无用的StringBuilder包装器有什么意义?

将与有人问您相同

创建无用的Cat包装器有什么意义?


1
那个非常好的答案中的关键思想是...“五年后”你现在想要这样做,而且你想在不破坏大量现有代码和/或强制重新验证所有代码的情况下完成。你没有编写原始代码。编写原始代码的人被面包车撞了。你很少有时间可靠地完成这项工作。抽象类以前不存在,因为它不是必需的。将其添加为实现cat的连接点是在这种(遗留...)程序中安全地移植新功能的方法。 - Mike Robinson
@MikeRobinson非常正确,即使您编写了原始类并且有很多时间,这仍然是正确的方法(或至少是*正确的方法之一)。不幸的是,在其他JDK领域中并不总是这种情况。 - user1803551

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接