Java Method Reference was introduced in Java 8, along with lambda expressions. The method reference is a shortcut way to create lambda expressions when it just calls a method.
Table of Contents
What is Java Method Reference?
The method reference allows us to create a lambda expression from an existing method. It’s used when the lambda expression is calling a function and doing nothing else. The JVM takes care of creating the lambda expression by mapping the input variables to the method arguments.
Method Reference Syntax
The method reference has two parts – class/object and method/constructor. They are separated by double colons (::). There are no additional parameters passed with the method reference.
Types of Method References
There are four types of method references in Java.
- Static Method Reference: its syntax is Class::StaticMethodName
- Reference to an Object instance method: the syntax is Object::instanceMethodName
- Reference to an instance method of an arbitrary object of specific type: the syntax is Class::instanceMethodName
- Constructor Reference: its syntax is ClassName::new

Java Method Reference Types
Java Method Reference Examples
Let’s look at the examples of all the four types of method references. We will first create a lambda expression and then use the method reference to have the same effect.
1. Static Method Reference
Let’s say we have a functional interface as below.
@FunctionalInterface
interface Counter {
int count(Object[] objArray);
}
We have a Utils class to get the number of elements in an array.
class Utils {
public static int countElements(Object[] array) {
return array.length;
}
}
We will use a lambda expression to call the Utils class countElements() method to get the number of elements in an array.
Integer[] intArray = { 1, 2, 3, 4, 5 };
// lambda expression
Counter counter2 = array -> Utils.countElements(array);
System.out.println(counter2.count(intArray)); // 5
Here, the lambda expression is simply calling the Utils class static method and not doing anything else. This is a perfect place to use a method reference to call the static method.
Counter counter = Utils::countElements;
2. Object Instance Method Reference
Let’s change the Utils class implementation and create an instance method.
class Utils {
public int count(Object[] array) {
return array.length;
}
}
Now, we will create a lambda expression calling this instance method.
Utils ut = new Utils();
Counter counter1 = array -> ut.count(array);
We can replace the lambda expression with instance method reference.
Counter counter1 = ut::count;
We can instantiate the Utils class in the method reference itself.
Counter counter1 = new Utils()::count;
3. Reference to the instance method of an arbitrary object
Sometimes, we call a method of an argument in the lambda expression. In that case, we can use a method reference to call an instance method of an arbitrary object of a specific type.
Let’s say we have a lambda expression like this.
String[] strArray = { "A", "E", "I", "O", "U", "a", "e", "i", "o", "u" };
Arrays.sort(strArray, (s1, s2) -> s1.compareToIgnoreCase(s2));
Here, the lambda expression is simply calling a method. So, we can use method reference here. But, the method is called on an arbitrary object of String. So, we can call the instance method by referring to the String class.
Arrays.sort(strArray, String::compareToIgnoreCase);
4. Constructor Method Reference
The Stream collect() method accepts a Supplier argument. The supplier should return a new instance every time. So, the lambda expression must call the constructor. Let’s look at a simple example.
List<Integer> intList = List.of(1, 2, 3, 4, 5);
String concat1 = intList.parallelStream().collect(
() -> new StringBuilder(),
(x, y) -> x.append(y),
(a, b) -> a.append(b)).toString();
Here, we can replace “() -> new StringBuilder()” to a constructor method reference.
String concat1 = intList.parallelStream().collect(
StringBuilder::new,
(x, y) -> x.append(y),
(a, b) -> a.append(b)).toString();
Well, we don’t have to stop here. The other two lambda expressions can also be replaced by a method reference.
String concat1 = intList.parallelStream().collect(
StringBuilder::new,
StringBuilder::append,
StringBuilder::append).toString();
How does method parameters get mapped and what about return type.