LongAdder类继承自哪个类?

3
在查看 LongAdder 的 JavaDocs 时,可以发现它继承了 Number 类。

Java docs LongAdder

然后在查看源代码时,它是从Striped64扩展而来的

LongAdder source code

我感到很困惑,为什么我们不能在javadocs中指定LongAdder扩展自Striped64类? 这是因为Striped64扩展了Number吗?


2
因为Striped64不是公共API,而Number是。 - Slaw
1
一个重要的额外考虑是,由于 Striped64 不是公共的,未来版本的 Java SE 可以自由更改这个层次结构:LongAdder 可以扩展一个完全不同的类,或直接扩展 Number。因此,任何依赖于任何方式存在 Striped64 的 java.util.concurrent.atomic 包之外的代码都是错误的代码。 - VGR
2个回答

5
LongAdder是继承自哪个类?
如源代码所示,它是继承自Striped64。然而,由于该类不是公共API,因此Javadoc没有告诉您这一点。
默认情况下,Javadoc只为public和protected成员生成文档;换句话说,只有公共API有文档1。Striped64类是包私有的,因此没有文档。由于这个类没有文档,找到的最接近的已记录祖先就是在这种情况下的Number。请注意,如果没有任何祖先是公共API,则可以具有15多个祖先的记录类Foo,但是如果没有一个祖先是公共API,则Javadoc将显示Foo扩展Object。
从公共API与私有API的角度来看,LongAdder扩展Striped64的事实是无关紧要的。后者是实现细节(即私有API)。公共API定义库的契约;因此,在这种情况下,用户只关心LongAdder是Number的子类。
如果需要,可以配置Javadoc以文档化所有内容,包括包私有和private成员。但是,生成的文档可能仅供内部使用(例如,用于维护库的组织内部)。
1. 确定API是公共的还是私有的不仅仅取决于可见性修饰符。类所在的包也是相关的。例如,JDK有许多包前缀为com.sun、oracle、jdk.internal等的类。这些包中的类是私有API,因此在公开可用的Javadoc中没有记录。
2. 随着模块的出现,Java 9中对“私有包”这个概念的认识得到了更加官方的地位。现在,您可以明确声明哪些包由模块导出,并且这由运行时强制执行。

1+; 那个 Striped64 真是太好了,以至于 guava 和其他一些项目不得不在他们的库代码中复制它。 - Eugene
1
同样地,StringBuilderStringBuffer被展示为扩展Object,隐藏了它们的共同、非公共基类AbstractStringBuilder - Holger

0

他们可能会在LongAdder中扩展Number类,谁知道呢?

来自Oracle文档:

enter image description here

enter image description here

可以得出结论,LongAdder通过扩展Striped64使用AtomicLong

问:为什么要通过LongAdder扩展Striped64?

答: Striped64持有一个Cells的哈希表(其中每个Cell都是AtomicLong的变体)。当多个线程用于向LongAdder(它扩展了Striped64)添加值时,线程将其值添加到该哈希表中的不同单元格中。这导致并发线程处理并增加吞吐量。

也许Striped64是一种内部实现,他们想要将其抽象化。


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