1.3.  Describe a lambda expression; refactor the code that uses an anonymous inner class to use a lambda expression; describe type inference and target typing

[Note]

Replacing Anonymous Inner Classes with Lambda Expressions

Portions of your code contain anonymous inner classes, which are sometimes difficult to follow. You would like to replace anonymous inner classes with code that is easier to read and maintain.

Replace the anonymous inner classes with lambda expressions. By doing so, development time will be much faster as there will be fewer lines of boilerplate code required. A typical Java Swing application utilizes anonymous inner classes to add functionality to application constructs. For instance, anonymous classes are a great way to add an action to a button. The problem is that inner classes can be difficult to follow, and they contain lots of boilerplate code.

The following lines of code demonstrate a typical anonymous inner class implementation for a button action implementation. Let's look at these lines of code before taking a look at how you can achieve the same solution using a lambda expression.

JButton button = ...
JLabel comp = ...

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        comp.setText("Button has been clicked");
    }
});
					

In this example, we are creating a new object that provides an implementation of the ActionListener interface. This interface has a single method, actionPerformed, which is called by the button instance when a user actually clicks the on-screen button. The anonymous inner class provides the implementation of this method.

Anonymous inner classes were designed to make it easier for Java programmers to pass around code as data. Unfortunately, they do not make it easy enough. There are still four lines of boilerplate code required in order to call the single line of important logic.

Boilerplate is not the only issue, though: this code is fairly hard to read because it obscures the programmer's intent. We do not want to pass in an object; what we really want to do is pass in some behavior. In Java 8, we would write this code example as a lambda expression, as shown in example below:

JButton button = ...
JLabel comp = ...

button.addActionListener(e -> comp.setText("Button has been clicked"));
					

Instead of passing in an object that implements an interface, we are passing in a block of code - a function without a name.

The 'e' is the name of a parameter (it can be any valid Java identifier), like the parameter in the anonymous inner class example.

The '->' separates the parameter from the body of the lambda expression, which is just some code that is run when a user clicks the button.

Another difference between this example and the anonymous inner class is how we declare the variable e. Previously, we needed to explicitly provide its type - ActionEvent e. In this example, we have not provided the type at all, yet this example still compiles. What is happening under the hood is that Java compiler is inferring the type of the variable e from its context - here, from the signature of addActionListener. It means that you do not need to explicitly write out the type when it is obvious.

[Warning]

In some situations where the Java compiler cannot infer types, you MUST explicitly specify values for type variables with type witnesses.

Example below demonstrates explicit type declaration (optional for this particular example) of lambda method parameter:

JButton button = ...
JLabel comp = ...

button.addActionListener((ActionEvent e) -> comp.setText("Button has been clicked"));
					

Syntax of Lambda Expressions

A lambda expression consists of the following:

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz