Spliterator.OfInt 中 tryAdvance 的奇怪实现

Weird implementation of tryAdvance in Spliterator.OfInt

它是如何工作的? Consumer<? super Integer>如何转换为IntConsumer??

default boolean tryAdvance(Consumer<? super Integer> action) {
    if (action instanceof IntConsumer) {
        return tryAdvance((IntConsumer) action);
    }
    else {
        if (Tripwire.ENABLED)
            Tripwire.trip(getClass(),
                      "{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
        return tryAdvance((IntConsumer) action::accept);
    }
}

强制转换为绑定方法引用 action::accept 提供 目标类型 ,它等同于 lambda x -> action.accept(x)IntConsumer 目标类型导致此 lambda(更愿意接受整数)适应接受 int(这将导致参数在传递给 action.accept() 之前被隐式装箱)。

您的问题不是很清楚,因为发布的代码中有 两个 类型转换。

第一个通过 instanceof 检查 Consumer<? super Integer> 是否也实现了 IntConsumer 然后进行普通类型转换,假设 class 实现 ConsumerIntConsumer 同时使用相同的语义。与 the documentation 比较:

Implementation Requirements:

If the action is an instance of IntConsumer then it is cast to IntConsumer and passed to tryAdvance(java.util.function.IntConsumer); otherwise the action is adapted to an instance of IntConsumer, by boxing the argument of IntConsumer, and then passed to tryAdvance(java.util.function.IntConsumer).

所以第一个 instanceof 检查和类型转换是契约的第一部分,如果 action 参数实现了两个接口,则避免装箱。

第二种类型转换是描述的对拳击 IntConsumer 改编的一部分,而拳击是由 method reference (IntConsumer) action::accept. This method reference refers to the method void accept(T t) (where T := ? super Integer) which can be adapted to the function signature of IntConsumer, as 暗示的。由于此功能签名不仅满足 IntConsumer 的签名,而且(当然)Consumer<? super Integer> 的签名需要类型转换来消除重载的 tryAdvance 方法之间的歧义。当使用等价的 lambda 表达式

时就没有必要了
return tryAdvance((int i)->c.accept(i));