Java 8 – Method Reference – Is it Magic?

Amongst the notable features in Java8, Method Reference adds Shorthand syntax for a lambda expression. In most cases, Lambda expression does nothing more than just calling a single method. If you find yourself doing that most often, its time to look at Method reference. It can be used to replace entire Lambda expression, let’s have a look at following example

class Student {
  int rollNo;
  String name;
  LocalDate birthDate;

//Getter and setter goes here.
}

The Student class captures basic details like Roll Number, Birth Date and Student name. Let’s define a collection to store some student information

public class StudentApplication {
  public static void main(String[] args) {
    List students = new ArrayList<>();
    students.add(createStudent("Michael Freit", 122, LocalDate.of(1998, 05, 12)));
    students.add(createStudent("Jeremy Kahn", 110, LocalDate.of(1998, 01, 03)));
    students.add(createStudent("Hugo Patrick", 95, LocalDate.of(1998, 03, 24)));
    students.add(createStudent("Nathan Hendrige", 130, LocalDate.of(1998, 02, 18)));
    students.add(createStudent("Kate hudson", 117, LocalDate.of(1998, 04, 10)));
  }

  private static Student createStudent(String name, int rollNo, LocalDate dateOfBirth) {
    Student student = new Student();
    student.setName(name);
    student.setRollNo(rollNo);
    student.setDateOfBirth(dateOfBirth);
    return student;
  }
}

What if you wish to simply print name of each student from the list. The pre-Java 8 syntax will be like

for(Student s : students){
  System.out.println(student.getName());
}

Using Java 8, Lambda expression syntax will look like below

students.stream().map(student -> student.getName()).forEach(s->System.out.println(s));

With Method expression, the code will look like

students.stream().map(Student::getName).forEach(System.out::println);

Notice student -> student.getName() is replaced with Student::getName and s->System.out.println(s) with System.out::println. In each of the Lambda expression, a single method was replaced with equivalent Method reference. Student::getName is a method reference of a defined type and System.out::println is an instance method of PrintStream object. In addition to that there are two more kinds.

  • Static method reference
  • Constructor reference

Static method reference
Static method reference requires a name of the class followed by the method name

Class::method

Let’s understand it by writing some code.

public class Library {
  public static void main(String[] args) {
    List shelf = new ArrayList<>();
    shelf.add("Blockchain revolution");
    shelf.add("Start with WHY?");
    shelf.add("Flying without Net");
  }

  private static void printBookName(String name) {
    System.out.println(name)
  }
}

To print name of each book

Java 7 or before

for(String book : shelf) {
  printBookName(book);
}

Java 8 with lambda

shelf.stream().forEach(s -> printBookName(s));

With Java 8 method reference

shelf.stream().forEach(Library::printBookName);

Constructor with new
This one is very easy, instead of using

new Integer();

use

Integer::new

So based on above examples Method Reference can be summarised as

Kind Pre-Java 8 Java 8
Static Method Class.staticMethod(); Class::staticMethod
Instance Method object.instanceMethod() object::instanceMethod
Instance Method of Specific Type sampleMethod(obj, args) { obj.callMe(args); } ObjectType::callMe
Constructor new SomeClass() SomeClass::new

That’s not all about Method Reference. Refer below example of how a thread can be created using a Method reference

public class ThreadDemo {
  public static void main(String[] args) {
    //Pre-Java 8
    Thread t = new Thread(new Runnable(){
      public void run(){
        ThreadDemo.printName();
      }
    });
    t.start();

   //Java8-Lambda
   Thread t2 = new Thread(()-> ThreadDemo.printName());
   t2.start();

   //Java8-Method reference
   Thread t3 = new Thread(ThreadDemo::printName);
   t3.start();
  }

  private static void printName(){
    System.out.println("I am inside Thread!!!");
  }
}

In next article, we will explore more about java.util.function package and identify how it fits with MethodReference and Lambda.

Be Sociable, Share!

Leave a Comment.