8.3 Method References
← Back to Chapter 8: Java 8 Features
Method references provide a compact, easy-to-read shorthand syntax for lambda expressions that simply invoke an existing method by name. They use the :: (double colon) operator.
What is a Method Reference?
A method reference is simply a shorter way of writing a Lambda expression when the Lambda is only calling an existing method.
Lambda Expressions - Provies the implementaion of already existing method
Method Reference - Refer the method directly without implementing it again
// Lambda:
Consumer<String> lambda = s -> System.out.println(s);
// Method Reference:
Consumer<String> methodRef = System.out::println;
Both essentially mean:
Take name and pass it to System.out.println().
The :: operator is called the method reference operator.
Why was Method Reference introduced?
Method references were introduced in Java 8, along with Lambda expressions.
The problem was that sometimes we write a Lambda that does nothing except call an existing method.
For example:
names.forEach(name -> System.out.println(name));
The Lambda is basically saying:
Take name and call System.out.println(name).
So Java 8 lets us shorten it:
names.forEach(System.out::println);
This makes the code:
shorter
cleaner
easier to read
Four Kinds of Method References
Java 8 categorizes method references into four distinct types:
| Type | Syntax | Lambda Equivalent | Example |
|---|---|---|---|
| 1. Static Method | Class::staticMethod | (args) -> Class.staticMethod(args) | Integer::parseInt |
| 2. Instance Method of a Particular Object | instance::method | (args) -> instance.method(args) | System.out::println |
| 3. Instance Method of an Arbitrary Object of a Given Type | Class::instanceMethod | (target, args) -> target.method(args) | String::toUpperCase |
| 4. Constructor Reference | Class::new | (args) -> new Class(args) | ArrayList::new |
1. Reference to a Static Method
Syntax: ContainingClass::staticMethodName
Function<String, Integer> parser1 = s -> Integer.parseInt(s);
Function<String, Integer> parser2 = Integer::parseInt;
List<Double> numbers = Arrays.asList(4.0, 16.0, 25.0);
List<Double> squareRoots = numbers.stream()
.map(Math::sqrt)
.collect(Collectors.toList());
2. Reference to an Instance Method of a Particular Object
Syntax: containingObjectRef::instanceMethodName
String prefix = "SARVY-";
Predicate<String> startsWithPrefix = prefix::startsWith;
PrintStream out = System.out;
Consumer<String> printer = out::println;
3. Reference to an Instance Method of an Arbitrary Object of a Specific Type
Syntax: ContainingType::methodName
Here, the first argument to the lambda becomes the target object upon which the method is invoked.
// Lambda: (s) -> s.toLowerCase()
Function<String, String> toLower = String::toLowerCase;
// Comparing two strings
List<String> names = Arrays.asList("David", "Alice", "Bob");
names.sort(String::compareToIgnoreCase);
4. Reference to a Constructor
Syntax: ClassName::new
// No-arg constructor via Supplier
Supplier<List<String>> listSupplier = ArrayList::new;
List<String> freshList = listSupplier.get();
// Parameterized constructor via Function
Function<String, User> userFactory = User::new;
User user = userFactory.apply("sarvy");
// Array Constructor Reference
IntFunction<String[]> arrayCreator = String[]::new;
String[] array = arrayCreator.apply(5); // Creates new String[5]
Lambda vs Method Reference: When to Use What?
| Scenario | Preferred Approach | Why? |
|---|---|---|
| Direct 1:1 call to existing method | Method Reference (String::trim) | Cleaner, removes redundant parameter noise |
| Arguments need modification or calculation | Lambda (x -> calculate(x * 2)) | Method reference cannot modify argument values |
| Ambiguous method overloads | Lambda ((String s) -> log(s)) | Resolves compiler overload ambiguity cleanly |
| Multi-statement business logic | Lambda or extract to private method | Keeps functional pipeline clean and readable |
Java 8
│
↓
Method Reference
│
::
│
┌─────────────┼─────────────┐
↓ ↓ ↓
Static method Instance Constructor
│ method │
│ │ │
Math::abs obj::method Class::new
│
│
Class::method
(arbitrary object)