Let's say I have method which takes a java.util.function.Predicate and return CompletableFuture:
public <R> CompletableFuture<R> call(Predicate<R> request) {
return new CompletableFuture<>();
}
If I call this method using an anonymous class like this:
Integer a = call(new Predicate<Integer>() {
@Override
public boolean test(Integer o) {
return false;
}
}).join();
It works because I have to explicitly declare the type of the Predicate. However, if I use lambda expression instead of anonymous class like this:
Integer a = call(o -> false).join();
It doesn't compile because Java thinks that it's a Predicate<Object>
and returns a message like this:
Error:(126, 42) java: incompatible types: java.lang.Object cannot be converted to java.lang.Integer
There are a few workarounds that I found. I may create the CompletableFuture
variable explicitly instead of chaining, or add an unnecessary extra argument Class<R>
that tells Java which type we want to get or force the type in lambda expression.
However I wonder why Java chooses Object
instead of Integer
in the first lambda example, it already knows which type I want to get so the compiler may use the most specific type instead of Object
because all of the three workarounds seems ugly to me.