Why is lambda return type not checked at compile time? Why is lambda return type not checked at compile time? java java

Why is lambda return type not checked at compile time?


In the first example, MyInterface::getLength and "I am NOT an Integer" helped to resolve the generic parameters T and R to MyInterface and Serializable & Comparable<? extends Serializable & Comparable<?>>respectively.

// it compiles since String is a SerializableFunction<MyInterface, Serializable> function = MyInterface::getLength;Builder.of(MyInterface.class).with(function, "I am NOT an Integer");

MyInterface::getLength is not always a Function<MyInterface, Integer> unless you explicitly say so, which would lead to a compile-time error as the second example showed.

// it doesn't compile since String isn't an IntegerFunction<MyInterface, Integer> function = MyInterface::getLength;Builder.of(MyInterface.class).with(function, "I am NOT an Integer");


Its the type inference that is playing its role here. Consider the generic R in the method signature:

<R> Builder<T> with(Function<T, R> getter, R returnValue)

In the case as listed:

Builder.of(MyInterface.class).with(MyInterface::getLength, "I am NOT an Integer");

the type of R is successfully inferred as

Serializable, Comparable<? extends Serializable & Comparable<?>>

and a String does imply by this type, hence the compilation succeeds.


To explicitly specify the type of R and find out the incompatibility, one can simply change the line of code as :

Builder.of(MyInterface.class).<Integer>with(MyInterface::getLength, "not valid");


It is because your generic type parameter R can be inferred to be Object, i.e. the following compiles:

Builder.of(MyInterface.class).with((Function<MyInterface, Object>) MyInterface::getLength, "I am NOT an Integer");