Unravel โบ Java concepts โบ Generics and functional
Method references
A method reference such as String::valueOf is a shorthand lambda that just calls an existing method: x -> String.valueOf(x).
Learn these first
At a glance
Pointing at an existing tool instead of describing it again: "use that one".
- 1Four forms: Type::staticMethod, object::instanceMethod, Type::instanceMethod (the first argument becomes the receiver, as in String::length) and Type::new (a constructor)
- 2It only works when the referenced method has a compatible signature with the functional interface expected
- 3Two forms you will meet constantly: this::handle passes a method of the current object as a callback, and String[]::new is an array constructor, used as list.toArray(String[]::new) or stream.toArray(String[]::new)
- 4Sorting is a typical home for them: Comparator.comparing(User::getName).thenComparing(User::getAge) reads almost like a sentence, where the lambda version needs two comparisons spelled out
- Prefer a method reference when it is as clear as the lambda; use a lambda if you need to adapt arguments or add logic
- A reference to an instance method of a particular object (logger::info) captures that object at the moment it is created, so the object it points to cannot change later
- It compiles to the same invokedynamic mechanism as a lambda, pointing straight at the target method handle with no extra synthetic method
// four forms of method reference, each shorthand for a lambdanames.stream().map(String::toUpperCase); // x -> x.toUpperCase()names.forEach(System.out::println); // x -> System.out.println(x)names.stream().map(Integer::parseInt); // x -> Integer.parseInt(x)Supplier<List<String>> make = ArrayList::new; // () -> new ArrayList<>()- line 2 x -> x.toUpperCase()
- line 3 x -> System.out.println(x)
- line 4 x -> Integer.parseInt(x)
- line 5 () -> new ArrayList<>()
Read the full explanation (about 1 min)
A method reference such as String::valueOf is a shorthand lambda that just calls an existing method: x -> String.valueOf(x).
A mental model
Pointing at an existing tool instead of describing it again: "use that one".
How it works
Four forms: Type::staticMethod, object::instanceMethod, Type::instanceMethod (the first argument becomes the receiver, as in String::length) and Type::new (a constructor).
It only works when the referenced method has a compatible signature with the functional interface expected.
Two forms you will meet constantly: this::handle passes a method of the current object as a callback, and String[]::new is an array constructor, used as list.toArray(String[]::new) or stream.toArray(String[]::new).
Sorting is a typical home for them: Comparator.comparing(User::getName).thenComparing(User::getAge) reads almost like a sentence, where the lambda version needs two comparisons spelled out.
Going deeper
Prefer a method reference when it is as clear as the lambda; use a lambda if you need to adapt arguments or add logic. Overloaded methods can make a method reference ambiguous.
A reference to an instance method of a particular object (logger::info) captures that object at the moment it is created, so the object it points to cannot change later. A reference of the Type::method form takes the receiver from the first argument instead, which is why String::length fits Function<String, Integer>.
Under the hood
It compiles to the same invokedynamic mechanism as a lambda, pointing straight at the target method handle with no extra synthetic method.
Common mistakes
- Ambiguity with overloaded methods.
- Confusing
Type::instanceMethodwith a static call.
How Unravel recognises it
When you paste code, Unravel looks for these signs of method references. Spotting them yourself is a good habit when you read unfamiliar code:
- Language constructs:
method-ref
Part of a learning path
- Modern Java: lambdas and streams ยท previous: Lambdas and functional interfaces ยท next: Generics
Related concepts
Frequently asked questions
What is Method references?
A method reference such as String::valueOf is a shorthand lambda that just calls an existing method: x -> String.valueOf(x).
What are the most common mistakes with Method references?
Ambiguity with overloaded methods. Confusing Type::instanceMethod with a static call.
How can I see Method references in real code?
Paste your own Java into Unravel and it will point out where method references appears, explain how it works at the detail level you choose, and draw the flow of the code around it.