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
instanceofwhether theConsumer<? super Integer>also implementsIntConsumerand does an ordinary type cast then, assuming that a class implementingConsumerandIntConsumerat the same time will do that with the same semantic. Compare with the documentation:So the first
instanceofcheck and type cast are the first part of the contract, avoiding boxing if theactionargument implements both interfaces.The second type cast is part of the described adaptation to a boxing
IntConsumerwhereas 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 ofIntConsumerbut also (of course) the signature ofConsumer<? super Integer>the type cast is needed to disambiguate between the overloadedtryAdvancemethods. It would be unnecessary when using the equivalent lambda expression