The following code compiles fine in IntelliJ and Eclipse, but the JDK compiler 1.8.0_25 complains. First, the code.
import java.util.function.Predicate;
public
If a lambda expression appears in a target type with wildcards (as in most cases)
Consumer<? super Boolean> consumer = b->{...}
the question arises - what's the type of the lambda expression; in particular, the type of b
.
Of course, there could be many choices due to the wildcards; e.g. we could explicitly choose
Consumer<? super Boolean> consumer = (Object b)->{...}
However, implicitly, b
should be inferred as Boolean
. This makes sense since the consumer should only be fed with Boolean
anyway.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.3
If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed, then the ground target type is the non-wildcard parameterization of T
(This probably assumes that wildcards are use properly variance-wise on the target type; we might find some hilarious examples if the assumption doesn't hold)
<? super E>
includes Object
, which isn't a Boolean
. ie
MyPredicate<? super E>
Could be a
MyPredicate<Object>
and you can't return an Object
as a boolean
.
Try changing your lambda to:
MyStream.<Boolean> create().filter(b -> Boolean.TRUE.equals(b));
which will compile and execute without error not matter the type of the stream, but will return true
for elements that are true
Boolean
values.