2

它是如何工作的?怎么能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);
    }
}
4

2 回答 2

5

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

于 2015-06-20T13:35:22.547 回答
2

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

第一个检查通过instanceof是否Consumer<? super Integer>也实现IntConsumer并执行普通类型转换,假设一个类同时实现ConsumerIntConsumer将使用相同的语义执行此操作。与文档比较:

实施要求

如果动作是 的实例,IntConsumer则将其强制转换为IntConsumer并传递给 ,否则通过将 的参数装箱,tryAdvance(java.util.function.IntConsumer);将动作适应于 的实例,然后传递给。IntConsumerIntConsumertryAdvance(java.util.function.IntConsumer)

因此,第一次instanceof检查和类型转换是合同的第一部分,如果action参数实现了两个接口,则避免装箱。

The second type cast is part of the described adaptation to a boxing IntConsumer whereas the boxing is implied by the 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 described by Brian Goetz. Since this functional signature does not only fulfill the signature of IntConsumer but also (of course) the signature of Consumer<? super Integer> the type cast is needed to disambiguate between the overloaded tryAdvance methods. It would be unnecessary when using the equivalent lambda expression

return tryAdvance((int i)->c.accept(i));
于 2015-06-22T08:53:37.983 回答