Method References in Java 8

Lochana Ranaweera
Lochness Writes
Published in
3 min readNov 9, 2015

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.

--

--