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

2

投稿されたコードには2 つの型キャストがあるため、質問は明確ではありません。

最初のものは、クラスが実装し、同時に同じセマンティックでそれを行うと仮定して、通常の型キャストも実装して実行instanceofするかどうかを介してチェックします。ドキュメントと比較してください:Consumer<? super Integer>IntConsumerConsumerIntConsumer

実装要件:

アクションが のインスタンスである場合はIntConsumer、 にキャストされてIntConsumerに渡されます。そうでない場合、アクションはの引数をボックス化することによってtryAdvance(java.util.function.IntConsumer);のインスタンスに適合され、に渡されます。IntConsumerIntConsumertryAdvance(java.util.function.IntConsumer)

したがって、最初のinstanceofチェックと型キャストはコントラクトの最初の部分であり、action引数が両方のインターフェイスを実装している場合はボックス化を回避します。

2 番目のタイプのキャストは、ボクシングへの記述された適応の一部ですが、ボクシングはメソッド参照IntConsumerによって暗示されます。このメソッド リファレンスは、Brian Goetz によって説明されているように、の関数シグネチャに適用できるメソッド(where ) を参照しています。この関数シグネチャは のシグネチャを満たすだけでなく、(もちろん)型キャストのシグネチャも満たすため、オーバーロードされたメソッド間のあいまいさを解消する必要があります。同等のラムダ式を使用する場合は不要です (IntConsumer) action::acceptvoid accept(T t)T := ? super IntegerIntConsumerIntConsumerConsumer<? super Integer>tryAdvance

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