Normally I would do:
Function<Integer, Integer> a = b -> b * 2;
System.out.println(a.apply(3)); // prints 6
I was amazed to see that following EL expression works:
${a = b -> b * 2; a(3)}
The result of above EL expression is 6
. How can compiler determine the type when declaring a
in snippet 2 but requires type information in snippet 1?
Even this compiles and executes fine:
${(b -> b * 2)(3)}
The target type of the lambda expressions is inferred from the context, which is an assignment statement to a Callable<String> reference variable. Subsequently, the reference variable is used to invoke the call() method.
The lambda expressions have a very simple, precise syntax and provide flexibility to specify the datatypes for the function parameters. Its return type is a parameter -> expression body to understand the syntax, we can divide it into three parts.
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
Lambda expressions basically express instances of functional interfaces (An interface with single abstract method is called functional interface. An example is java.lang.Runnable). lambda expressions implement the only abstract function and therefore implement functional interfaces.
The EL evaluator / executor has no idea about the exact type of a in your EL expression. It just knows it should be a Number
because of * operation
${a = b -> b * 2; a(3)}
Take a look at these results:
${a = b -> b * 2; a(3)}
6
${a = b -> b * 2; a('32')}
64
${a = b -> b * 2; a('32s')}
java.lang.NumberFormatException: For input string: "32s"
So only at runtime you will get an Exception, because Long.parse("32s")
fails.
Look at this source code of ELArithmetic.java#211
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With