Method References

Basic Java
≈ 2 min read

When a lambda only calls an existing method

A lambda often contains no new logic and simply passes its argument to an existing method. In that case, the code can be shortened with a method reference.

Function<String, Integer> length1 = text -> text.length();
Function<String, Integer> length2 = String::length;

Both variables describe the same behavior. The String::length form does not call the method when it is declared — it passes behavior that will be invoked later through the functional interface.

Main method-reference forms

In practice, four forms appear most often:

Function<String, Integer> parse = Integer::parseInt;
Consumer<String> print = System.out::println;
Function<String, String> trim = String::trim;
Supplier<ArrayList<String>> create = ArrayList::new;
  • Integer::parseInt — a reference to a static method;
  • System.out::println — a method of a specific object;
  • String::trim — an instance method where the object itself is supplied as an argument of the functional interface;
  • ArrayList::new — a constructor reference.

The number and types of parameters must match the expected functional interface. For example, String::trim fits Function<String, String>: the input string becomes the object on which trim() is called, and the method result becomes the function result.

Choose the readable form

A method reference is useful when it actually makes the intention clearer. If a lambda contains an additional check, several calls, or a calculation, a regular lambda is usually easier to read.

Predicate<String> isNotBlank = text -> !text.isBlank();

Here, trying to replace the lambda with a method reference at any cost would only make the code more complicated. Method references are not a separate computation mechanism; they are a more compact form for already existing compatible behavior.