Java 为什么拆分器';s getExactSizeIfKnown()未调用hasCharacteristics()

Java 为什么拆分器';s getExactSizeIfKnown()未调用hasCharacteristics(),java,java-8,java-stream,spliterator,Java,Java 8,Java Stream,Spliterator,在Spliterator类的源代码(JDK 1.8.040)中,default实现getExactSizeIfKnown()通过调用抽象特征()检查正在操作的实例是否具有大小特征方法并检查它是否包含size,而不是只调用hasCharacteristics(size)方法,该方法有一个默认的实现,它做的事情几乎相同 是否有任何原因导致getExactSizeIfKnown()未实现为: return !hasCharacteristics(SIZED) ? -1L : estimateSize(

Spliterator
类的源代码(JDK 1.8.040)中,
default
实现
getExactSizeIfKnown()
通过调用
抽象特征()检查正在操作的实例是否具有
大小
特征
方法并检查它是否包含
size
,而不是只调用
hasCharacteristics(size)
方法,该方法有一个
默认的
实现,它做的事情几乎相同

是否有任何原因导致
getExactSizeIfKnown()
未实现为:

return !hasCharacteristics(SIZED) ? -1L : estimateSize();
这对我来说更清楚,并且似乎可以更好地处理重写默认行为(目前,如果
hasCharacteristics(int)
被重写为一些奇怪的东西,没有迹象表明
getExactSizeIfKnown()
可能也应该被重写)


这里有我遗漏的东西吗?为什么要在这样的方法之间重复检查?

这个问题显然是在
拆分器
类的设计过程中提出的。引用OpenJDK邮件列表中的Paul Sandoz:

Mike Duigou的帖子
-
getExactSizeIfKnown()
-是否使用
hasCharacteristics

我们可以,不这样做稍微有效一些

因此,似乎没有强有力的理由,只有一个次要的性能考虑

另一方面,我认为你关于将hasscharacteristics(int)
重写为“奇怪的东西”的论点并不成立。如果要覆盖
hasscharacteristics(int)
,则
characteristics()
的实现还需要与该“奇怪”行为保持一致,否则将违反拆分器的约定。注意,实施规范(描述符合性实施所需的行为)说明:

如果
Spliterator
报告了
size
的特征,则默认实现返回
estimateSize()
的结果,否则返回-1


基于此,如果您覆盖拆分器特性的行为,您将被警告默认情况下,
getExactSizeIfKnown()
将受到影响。

我发现Paul Sandoz说过“我们可以,不这样做效率略高。”我看不出有什么理由按照您建议的方式实施它。两个方向的所有论据似乎都相当薄弱。所以我猜实施者只是简单地选择了他们个人喜欢的一个。@Tunaki挖得不错!对我来说,这只是改变文档以明确说明问题的一个理由,而不是改变实现。此外,您正在查看默认方法与抽象方法。想想哪一个是必须的,什么是应该实施的,哪个是不行的。代码>hasCharacteristics
在整个JDK中只被重写一次,它所做的只是委托给一个包装好的拆分器。所以我坚持我的主张,没有强有力的理由说明它应该以不同的方式实现。@Tom Tresansky:如果你将
hasCharacteristics(int)
“重写为奇怪的东西”,其结果与同一类的
characteristics()
实现的结果相矛盾,你是唯一要为接下来发生的事情负责的人。这个类要求保持
characteristics()
hasCharacteristics(int)
同步是一个很好的观点,这避免了这个问题。