Skip to main content

Method References

Method References are a special type of syntactic sugar introduced in Java 8. They provide a shorter, more readable alternative to Lambda expressions when the lambda expression does absolutely nothing except call an existing method.

The syntax uses a double-colon :: operator to separate the class/object name from the method name.


The Core Concept

If your lambda expression looks like this: str -> System.out.println(str)

You are taking an argument (str) and simply passing it straight into another method (println). Because the compiler is smart enough to figure out that the argument should be passed to the method, you can rewrite it using a Method Reference like this: System.out::println


Types of Method References

There are four primary types of Method References in Java.

1. Reference to a Static Method

Syntax: ClassName::staticMethodName

import java.util.function.Function;

public class LabMethodRef1 {

public static void main(String[] args) {
// Using a Lambda
Function<String, Integer> parseLambda = (str) -> Integer.parseInt(str);

// Using a Method Reference!
Function<String, Integer> parseRef = Integer::parseInt;

System.out.println(parseRef.apply("100")); // Output: 100
}
}

2. Reference to an Instance Method of a Particular Object

Syntax: objectRef::instanceMethodName

import java.util.function.Consumer;

public class LabMethodRef2 {

public static void main(String[] args) {
// System.out is an object of PrintStream!

// Using a Lambda
Consumer<String> printLambda = (str) -> System.out.println(str);

// Using a Method Reference!
Consumer<String> printRef = System.out::println;

printRef.accept("Hello World!");
}
}

3. Reference to an Instance Method of an Arbitrary Object of a Particular Type

Syntax: ClassName::instanceMethodName

This one is slightly confusing. It is used when the method you want to call belongs to the object that is passed as the argument to the lambda.

import java.util.function.Function;

public class LabMethodRef3 {

public static void main(String[] args) {
// Using a Lambda.
// Notice how 'str' is the argument, and we are calling a method ON 'str'
Function<String, String> lowerLambda = (str) -> str.toLowerCase();

// Using a Method Reference!
// We refer to the class of the argument (String) and the method to call.
Function<String, String> lowerRef = String::toLowerCase;

System.out.println(lowerRef.apply("JAVA")); // Output: java
}
}

4. Reference to a Constructor

Syntax: ClassName::new

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class LabMethodRef4 {

public static void main(String[] args) {
// Using a Lambda
Supplier<List<String>> listLambda = () -> new ArrayList<>();

// Using a Constructor Reference!
Supplier<List<String>> listRef = ArrayList::new;

List<String> myList = listRef.get();
}
}

[!TIP] You are never strictly required to use a Method Reference instead of a Lambda. However, most modern IDEs (like IntelliJ or Eclipse) will automatically highlight Lambdas that can be converted into Method References and suggest the change, as it is considered a best practice for clean code.