What are the four forms of method reference in Java, and what does each one mean?
Method references are shorthand for lambdas that call an existing method. You write the method name, two colons, and optionally the receiver or the type. There are exactly four forms, and each maps onto a different functional interface shape.
Static method reference — Integer::parseInt. The receiver is the class, and the functional interface's argument becomes the method's argument.
Bound instance method reference — "hello"::toUpperCase. The receiver is a fixed object, and the functional interface takes no arguments, because the receiver already supplies them. This is the form that lets you use a Supplier when you have one object.
Unbound instance method reference — String::length. The functional interface's first argument becomes the receiver, and the remaining arguments are passed to the method. A Function<String, Integer> matches length, because the String is the receiver and the method needs nothing else.
Constructor reference — ArrayList::new. It calls a constructor, and the functional interface's arguments are the constructor's arguments. A Supplier can use the no-argument constructor, or a Function<Integer, ArrayList> can use the one that takes a capacity.
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
// 1. Static method reference.
Function<String, Integer> parse = Integer::parseInt;
System.out.println("static : " + parse.apply("42"));
// 2. Instance method of a bound object.
Supplier<String> upper = "hello"::toUpperCase;
System.out.println("bound : " + upper.get());
// 3. Instance method where the receiver is the first argument.
Function<String, Integer> length = String::length;
System.out.println("unbound : " + length.apply("tutorsbot"));
// 4. Constructor reference.
Function<Integer, java.util.ArrayList<String>> list = java.util.ArrayList::new;
System.out.println("constructor: " + list.apply(3).size());
// A two-argument static method.
BiFunction<String, String, Boolean> eq = String::equalsIgnoreCase;
System.out.println("bi : " + eq.apply("JAVA", "java"));
}
}The output shows each form doing exactly what the theory predicts. The static reference parses a string into an integer. The bound reference uppercases a fixed string with no argument. The unbound reference measures whichever string it is handed. The constructor reference builds a list with the capacity it is given.