Java 8 Method References

02 July 2014
By Gonçalo Marques
 
java java8
In this article we will cover Java 8 method references.

Method References

As we have seen in Java 8 Lambda expressions example Java 8 introduced the concept of Functional Interfaces, which in turn may be implemented by the means of lambda expressions.

As a reminder, a Functional Interface is an interface containing a single abstract method, ie. a method that is not implemented.

Considering the following Functional Interface:
Operation.java

public interface Operation<I, O> {
  O calculate(I input);
}

And the following class:
Calculator.java

public class Calculator {

  public static int square(int a) {
    return a * a;
  }

}

We may use the functional interface to get a reference to the Calculator static method:

Static method reference

Operation<Integer, Integer> operation = Calculator::square;

// Prints the value 9
System.out.println(operation.calculate(3));

We may get references to any existing static method that matches our Functional Interface:

Static method reference to Integer.parseInt()

Operation<String, Integer> operation = Integer::parseInt;

// Prints the integer 9
System.out.println(operation.calculate("34"));

It is also possible to get references to instance methods. Let's change our Calculator class:

Calculator.java

public class Calculator {

 int a = 4;

 public int sum(int b) {
  return a + b;
 }

 public static int square(int a) {
  return a * a;
 }

}

We may get a reference to the sum instance method:

Instance method reference

Calculator calculator = new Calculator();
Operation<Integer, Integer> operation = calculator::sum;

// Prints the value 7
System.out.println(operation.calculate(3));

Arbitrary instance methods may also be referenced:

Arbitrary instance method reference

Operation<String, Integer> operation = String::length;

// Prints the value 11
System.out.println(operation.calculate("Hello World"));

The compiler will expect that a String instance is passed into our method reference. Since length returns an integer, it will perfectly match the Functional Interface we declared in order to hold the method reference (input of type String and output of type Integer).

Finally we may also have references to Constructor methods. Considering the following class:

Person.java

public class Person {

  private String name;
  private int age;

  public Person(String name) {
    this.name = name;
  }

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public String getName() {
    return name;
  }

  public int getAge() {
    return age;
  }

}

And a Functional Interface that represents a person factory:

PersonFactory.java

public interface PersonFactory {

  Person producePerson(String name);

}

We may reference the Constructor using a method reference:

Constructor method reference

PersonFactory personFactory = Person::new;
Person person = personFactory.producePerson("John Smith");

// Prints "John Smith"
System.out.println(person.getName());

The compiler will match the Functional Interface method producePerson(String name) with the single argument constructor of our class Person.

Reference

Method References (The Java(TM) Tutorials, Learning the Java Language, Classes and Objects)

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: