What are Method References in Java?

Method references in Java are a feature that was introduced in Java 8. They provide a way to refer to a method without actually executing it. They are often used in conjunction with Java’s functional programming features, such as Streams and Lambdas, where a method to be executed is often expected as a parameter.

The syntax for a method reference is the name of the class (or the name of an object), followed by :: and the method’s name. Here’s an example:

List<String> words = Arrays.asList("Hello", "Method", "References", "In", "Java");

// Let's use a method reference to print each word in the list
words.forEach(System.out::println);

In the above code, System.out::println is a method reference. The forEach method expects a lambda that takes a parameter and does something with it. Here, the println method of the System.out class is being referenced, and it will be used to print each word in the list.

There are four types of method references in Java:

  1. Static method reference: They refer to the static methods of a class. For example, ClassName::staticMethodName.
  2. Instance method reference of a particular object: They refer to the instance methods of a particular object. For example, in above code System.out::println.
  3. Instance method reference of an arbitrary object: They refer to the instance methods where the first parameter is the target of the method. For example, String::length.
  4. Constructor reference: They refer to the constructor of a class. For example, ClassName::new.

Let’s take a deeper look at the four kinds of method references with more elaborated examples.

1. Static method references:

Static method references can be used when the method to be invoked is a static method. For example:

package org.kodejava.basic;

import java.util.stream.Stream;

public class StaticMethodRef {
    public static void main(String[] args) {
        String[] array = {"Java", "Python", "Ruby", "JavaScript"};
        Stream.of(array).forEach(StaticMethodRef::printStr);
    }

    static void printStr(String str) {
        System.out.println("printStr method called with value: " + str);
    }
}

In this example, the printStr method is a static method, and we reference this method using StaticMethodRef::printStr.

2. Instance method reference of a particular object:

Instance method references can be used when the method to be invoked is an instance method. For example:

package org.kodejava.basic;

import java.util.stream.Stream;

public class InstanceMethodRef {
    public static void main(String[] args) {
        InstanceMethodRef instance = new InstanceMethodRef();
        String[] array = {"Java", "Python", "Ruby", "JavaScript"};
        Stream.of(array).forEach(instance::printInstanceStr);
    }

    void printInstanceStr(String str) {
        System.out.println("printInstanceStr method called with value: " + str);
    }
}

In this example, printInstanceStr is an instance method, and we create an instance of InstanceMethodRef and refer to an instance method instance::printInstanceStr.

3. Instance method reference of an arbitrary object:

We can do this when we have a collection of instances and want to invoke a method on them. For example:

package org.kodejava.basic;

import java.util.stream.Stream;

public class InstanceMethodReferenceArbitrary {
    public static void main(String[] args) {
        String[] array = {"Java", "Python", "Ruby", "JavaScript"};
        Stream.of(array).map(String::toUpperCase).forEach(System.out::println);
    }
}

In this example, String::toUpperCase invokes the toUpperCase method for every instance of the String in the Stream.

4. Constructor reference:

Constructor references are used for a constructor call. For example:

package org.kodejava.basic;

import java.util.stream.Stream;

class Student {
    String name;

    Student(String name) {
        this.name = name;
    }
}

public class ConstructorReference {
    public static void main(String[] args) {
        Stream.of("John", "Martin", "Don")
                .map(Student::new)
                .forEach(student -> System.out.println("Student name is: " + student.name));
    }
}

In the above example, Student::new creates a new instance of Student.

Wayan

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.