Method Reference in Java 8

In Java, a method is a block of code that performs a specific task. When you want to use a method, you typically call it by its name and pass any required arguments.

However, in Java 8, you can also reference a method without calling it, and this is called a method reference.

Method reference is a shorthand syntax for lambda expressions. It allows you to refer to an existing method and pass it as a parameter to another method. Method references can make your code more concise and easier to read.

There are four types of method references in Java 8.

Reference to a static method

 

This is used to reference a static method of a class. The syntax for this type of method reference is:

 

ClassName::staticMethodName

 

Suppose we have a class called StringUtils that contains a static method called reverse that takes a String as input and returns the reverse of the input string.

 

public class StringUtils {
    public static String reverse(String input) {
        StringBuilder builder = new StringBuilder(input);
        return builder.reverse().toString();
    }
}

 

Now let's say we have a list of strings that we want to reverse and print. We can use the reverse() method defined in StringUtils class as follows:

 

import java.util.ArrayList;
import java.util.List;

public class StaticMethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("John");
        names.add("Mary");
        names.add("Tom");

        // Using lambda expression
        names.forEach(name -> System.out.println(StringUtils.reverse(name)));

        // Using method reference
        names.forEach(StringUtils::reverse);
    }
}

 

In this example, we use a lambda expression and a method reference to print the reverse of each string in the list. 

In the lambda expression, we call the reverse() method of StringUtils class by passing the string as an argument.

In the method reference, we simply pass the StringUtils::reverse as a reference to the reverse() method. This is possible because reverse() method is a static method.

 

Reference to an instance method of an object

This is used to reference an instance method of an object. The syntax for this type of method reference is:

 

object::instanceMethodName

Suppose we have a class called Person that contains a method called sayHello() that prints a greeting message.

 

public class Person {
    private String name;

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

    public void sayHello() {
        System.out.println("Hello, my name is " + name);
    }
}

 

Now let's say we have a list of Person objects and we want to call the sayHello() method of each person in the list. We can use the sayHello() method defined in Person class as follows:

 

import java.util.ArrayList;
import java.util.List;

public class InstanceMethodReferenceExample {
    public static void main(String[] args) {
        List<Person> people = new ArrayList<>();
        people.add(new Person("John"));
        people.add(new Person("Mary"));
        people.add(new Person("Tom"));

        // Using lambda expression
        people.forEach(person -> person.sayHello());

        // Using method reference
        people.forEach(person::sayHello);
    }
}

 

In this example, we use a lambda expression and a method reference to call the sayHello() method of each Person object in the list.

In the lambda expression, we call the sayHello() method of Person object by using the person parameter. In the method reference, we simply pass the Person::sayHello as a reference to the sayHello() method. This is possible because we are referencing an instance method of an object.

 

Reference to an instance method of a class

This is used to reference an instance method of a class. The syntax for this type of method reference is:

ClassName::instanceMethodName

 

Here is an example that demonstrates how to reference an instance method of a class:

import java.util.Arrays;
import java.util.List;

public class MethodReferenceExample {

    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        // Using a lambda expression
        names.forEach(name -> System.out.println(name));

        // Using a method reference
        names.forEach(System.out::println);
    }
}

 

In this example, we have a list of names and we want to print each name to the console.

First, we use a lambda expression to define a function that takes a name as input and prints it to the console.

We then use the forEach method of the List interface to apply this function to each name in the list. Next, we use a method reference to reference the println method of the PrintStream class.

This method takes a single parameter of type String, which matches the type of input to our function. We use the System.out object to reference the PrintStream instance, and then use the double colon (::) operator to reference the println method.

Both the lambda expression and the method reference achieve the same result in this example, but the method reference provides a more concise and readable syntax for calling an instance method of a class.

 

Reference to a constructor

This is used to reference a constructor of a class. The syntax for this type of method reference is: 

ClassName::new

Let's say we have a Vehicle class with a constructor that takes one parameter - model.

 

public class Vehicle {
    private String model;

    public Vehicle(String model) {
        this.model = model;
    }

    // getters and setters
}

 

Now let's say we want to create a new Vehicle object using a reference to the constructor. We can do this using the following code:

 

VehicleFactory vehicleFactory = Vehicle::new;
Vehicle vehicle = vehicleFactory.createVehicle("Honda");

 

VehicleFactory vehicleFactory = Vehicle::new;
Vehicle vehicle = vehicleFactory.createVehicle("Honda");

 

In this example, we create a VehicleFactory object using a reference to the Vehicle constructor (Vehicle::new). We can then use the createVehicle method on the vehicleFactory object to create a new Vehicle object with the model "Honda".

Note that the VehicleFactory interface is defined as follows:

 

public interface VehicleFactory {
    Vehicle createVehicle(String model);
}

 

The createVehicle method takes a String parameter, which corresponds to the model parameter of the Vehicle constructor.

 

Overall, method references are a powerful and useful feature of Java 8 that make it easier to write functional-style code.