Method References in Java 8
In the previous post, I discussed what lambda-expressions are. In this post, I will explain the concept of method references brought about in Java 8.
Sometimes there is already a method that you’d like to pass on to some other code. Of course, you could use a lambda-expression to carry this out.
Let’s start with an example:
Suppose you want to print the event object whenever a particular button is clicked. The following project was built as JavaFX as Java 8 uses JavaFX as the successor to the Swing GUI toolkit. Feel free to obtain the project from this GitHub repository of mine.
Notice that in the Main class, a button has been created and a lambda-expression has been used to set the callback action on button click event. I could have used what many programmers call “anonymous instance of the anonymous class” syntax (included as a comment in the code) to do the same, but instead I have used a lambda-expression to keep it short and simple.
package sample;import javafx.application.Application;
//import javafx.event.ActionEvent;
//import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;/**
* Created by lochana
*/public class Main extends Application {@Override
public void start(Stage primaryStage) throws Exception {Button myButton = new Button();
myButton.setText(“Click Me”);StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 150);
root.getChildren().add(myButton);
primaryStage.setTitle(“Method Reference Example”);
primaryStage.setScene(scene);
primaryStage.show();//button callback without using lambda expression
/*myButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
System.out.println(event);
}
});*///button callback using lambda expression
myButton.setOnAction(event -> System.out.println(event));
}public static void main(String[] args) {launch(args);
}
}
So what is the relationship between method reference and lambda-expressions?
Method reference is a shortcut which can be used at any place where a lambda expression is applicable.
In the above example, it will be convenient if we can just pass the println method to the setOnAction method. Method referencing in Java 8 allows us to do that. Therefore, the lambda-expression in the Main class can be replaced with an equivalent method reference as shown below.
package sample;import javafx.application.Application;
//import javafx.event.ActionEvent;
//import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;/**
* Created by lochana
*/public class Main extends Application {@Override
public void start(Stage primaryStage) throws Exception {Button myButton = new Button();
myButton.setText(“Click Me”);StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 150);
root.getChildren().add(myButton);
primaryStage.setTitle(“Method Reference Example”);
primaryStage.setScene(scene);
primaryStage.show();//button callback using lambda expression
//myButton.setOnAction(event -> System.out.println(event));//button callback with equivalent method reference
myButton.setOnAction(System.out::println);}public static void main(String[] args) {launch(args);
}
}
Syntax of method references:
A method reference is stated with the class name or the object name followed by the :: operator and finally the method name. There are three kinds of cases.
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
In the first two cases, the lambda-expression that is equivalent to the method reference supplies the parameters of the method. In the example I have given, you can see the System.out::println is a method reference that is equivalent to the lambda expression x -> System.out.println(x).
You may feel that the first case and the third case are similar. But there IS a difference. In the first case, the reference is to an instance method of a specific object. In the third case, the reference is to an instance method of an arbitrary object supplied later. Also in the third case, the first parameter of the lambda-expression will be the target of the method. As such, a method reference of the third type will be equivalent to a lambda-expression like (s) -> s.theMethod( )
Tips:
- The this parameter can be included in a method reference. For an example, this::equals is the same as the lambda-expression x -> this.equals(x)
- The usage of super can also be captured in method references.