How does it work?
How can Consumer<? super Integer>
be cast to 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);
}
}
Your question isn’t quite clear as there are two type casts in the posted code.
The first one checks via
instanceof
whether theConsumer<? super Integer>
also implementsIntConsumer
and does an ordinary type cast then, assuming that a class implementingConsumer
andIntConsumer
at the same time will do that with the same semantic. Compare with the documentation:So the first
instanceof
check and type cast are the first part of the contract, avoiding boxing if theaction
argument implements both interfaces.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 methodvoid accept(T t)
(whereT := ? super Integer
) which can be adapted to the function signature ofIntConsumer
, as described by Brian Goetz. Since this functional signature does not only fulfill the signature ofIntConsumer
but also (of course) the signature ofConsumer<? super Integer>
the type cast is needed to disambiguate between the overloadedtryAdvance
methods. It would be unnecessary when using the equivalent lambda expression