Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A Java method reference is a syntactic shorthand for a lambda expression that invokes an existing method or constructor. It acts as an uninvoked, strongly-typed pointer to a method, allowing that method to be passed as an instance of a functional interface. The Java compiler automatically maps the parameters and return type of the functional interface’s single abstract method (SAM) to the referenced method. The syntax utilizes the double-colon operator (::), separating the target reference (class or instance) from the method name. Parentheses are strictly omitted because the method is being referenced, not executed.
Qualifier::methodName
There are four distinct categories of method references, defined by how the compiler resolves the target instance and maps the functional interface parameters.

1. Reference to a Static Method

This references a static method belonging to a class. The arguments provided by the functional interface are passed directly as arguments to the static method. Syntax: ClassName::staticMethodName
// Functional Interface: R apply(T t)
// Lambda equivalent: (str) -> Integer.parseInt(str)
Function<String, Integer> parser = Integer::parseInt;

2. Reference to an Instance Method of a Particular Object

This references an instance method bound to a specific, pre-existing object in memory. The functional interface arguments are passed directly to the method invoked on that specific object. Syntax: instanceReference::methodName
// Functional Interface: boolean test(T t)
// Lambda equivalent: (str) -> "Prefix".startsWith(str)
String prefix = "Prefix";
Predicate<String> prefixChecker = prefix::startsWith;

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

This references an instance method where the target object is not known at the time the reference is created, but will be provided at invocation. The compiler maps the first parameter of the functional interface as the target receiver (the instance on which the method is called), and any subsequent parameters are passed as arguments to the method. Syntax: ClassName::instanceMethodName
// Functional Interface: int compare(T o1, T o2)
// Lambda equivalent: (s1, s2) -> s1.compareToIgnoreCase(s2)
Comparator<String> stringComparator = String::compareToIgnoreCase;

4. Constructor Reference

This references a class constructor to instantiate a new object. The compiler resolves which overloaded constructor to invoke by matching the parameter signature of the functional interface’s abstract method. Array constructors can also be referenced using Type[]::new. Syntax: ClassName::new
// Functional Interface: R apply(T t)
// Lambda equivalent: (capacity) -> new StringBuilder(capacity)
Function<Integer, StringBuilder> builderFactory = StringBuilder::new;

// Array Constructor Reference
// Lambda equivalent: (size) -> new String[size]
IntFunction<String[]> arrayFactory = String[]::new;

Signature Matching and Resolution

For a method reference to compile, the referenced method must be strictly compatible with the target functional interface. The compiler enforces the following rules during resolution:
  1. Parameter Count: The number of parameters must match exactly, accounting for the implicit target receiver in Type 3 references.
  2. Parameter Types: The parameter types of the functional interface must be assignable to the parameter types of the referenced method (contravariance).
  3. Return Type: The return type of the referenced method must be assignable to the return type of the functional interface (covariance). If the functional interface returns void, the referenced method can return any type (the return value is discarded).
  4. Exceptions: Any checked exceptions thrown by the referenced method must be declared in the throws clause of the functional interface’s abstract method.
Master Java with Deep Grasping Methodology!Learn More