Java Reference
In-Depth Information
The preceding example demonstrates a couple of concepts. First, the expression accepts a parameter (
a
), and the
ternary operator says that if
a
is equal to
0
, then
1
will be returned; otherwise, the product of
a * a
will be returned.
Therefore, this example demonstrates the use of EL operators within a lambda expression. Second, note that this
expression contains no parentheses. That is because parentheses are optional if there is only one parameter being
passed into a lambda. If there are two or more parameters in use, then parentheses are required.
Variable Assignment
Sometimes it is useful to assign expressions to variables so that they can be passed around and utilized at a later time.
This holds true for lambda expressions, because it allows for the encapsulation of a function, much like the concept of
closures. The following EL demonstrates this concept by creating a lambda that returns the square root of a value that
is passed in as a parameter:
// Assign the lambda to an identifier
sqrt = x -> x * x
// Use the lambda at a later point
sqrt(10) // returns 100
Nesting
Nesting a lambda expression inside another can produce very useful results. It is important to note that the scope
within lambda functions is to the body of the lambda itself. Therefore, any identifiers, variables, or arguments that
are defined inside a lambda body are available only within the scope of that expression. This can be useful for nesting
because objects that are defined within a lambda can be passed to nested expressions but not vice versa. Take the
following example, for instance:
c->[(c.num1, c.num2) -> x + y ]
In the previous expression, the
c
identifier would be an object that contains
num1
and
num2
. Within the lambda,
the
c
object is broken out and then used to find the sum of the two numbers, and then the result is returned.
Passing Lambdas to Java
It is possible to pass lambda expressions to Java code for evaluation, which can be beneficial to developers for
a couple of reasons. First, having the ability to pass lambda expressions written in EL to a Java class provides the
option to change that lambda at a later date without recompiling the Java code. This means that in a production
environment, lambda expressions can be changed without redeploying an application.
Another good reason to pass lambdas to Java is so that you can utilize lambdas in code bases that are compiled
using pre-Java 8 versions of the JDK. Lambdas are not available for use within Java code prior to the release of JDK 8;
therefore, in order to benefit from the use of lambdas in Java, code bases will need to be migrated to JDK 8. This may
not always be possible for a multitude of reasons. Therefore, for backward compatibility, lambda expressions may be
written an EL and then passed to Java code that is compiled under JDK 7. Lastly, passing lambdas from EL to Java can
aid in situations such as when there is a need to support query expressions on collections.
Let's take a look at how you can utilize EL lambda expressions from Java. Suppose you are using an EL lambda
expression in a JSF view; then it could be passed to a managed bean method for evaluation, and a result could be
returned. To accept a lambda expression, the Java method must accept a
javax.el.LambdaExpression
as a parameter.
The lambda expression can then be invoked by calling its
invoke
method, which will return the result of the lambda.
The following EL is contained in a JSF view named
chapter03\PassToJava.xhtml
. The lambda expression in the
EL is passed to a managed bean function named
elExampleBean
.