BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Generics and functional

Java language

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

Mental model

Pointing at an existing tool instead of describing it again: "use that one".

What happens, in order
  1. 1Four forms: Type::staticMethod, object::instanceMethod, Type::instanceMethod (the first argument becomes the receiver, as in String::length) and Type::new (a constructor)
  2. 2It only works when the referenced method has a compatible signature with the functional interface expected
  3. 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)
  4. 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
Remember
Watch out
Ambiguity with overloaded methodsConfusing Type::instanceMethod with a static call
Example (highlighted lines explain it)
// 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<>()
  1. line 2 x -> x.toUpperCase()
  2. line 3 x -> System.out.println(x)
  3. line 4 x -> Integer.parseInt(x)
  4. 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::instanceMethod with 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:

Part of a learning path

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.