Method references: four kinds

Java 8 Course · lesson 4 of 16 · 3 min read

Know which of the four forms you are writing, because they bind arguments differently.

Open this lesson in the learning hub

Key points

  • A method reference is a lambda whose body does nothing but call one existing method.
  • Static: Integer::parseInt is s -> Integer.parseInt(s).
  • Bound: System.out::println - the receiver is fixed already.
  • Unbound: String::toUpperCase - the first lambda argument becomes the receiver.
  • Constructor: ArrayList::new feeds straight into collectors and factories.

Example

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        // 1. static
        Function<String, Integer> parse = Integer::parseInt;
        System.out.println("static      : " + (parse.apply("41") + 1));

        // 2. bound - receiver already chosen
        Consumer<Object> out = System.out::println;
        out.accept("bound       : receiver is System.out");

        // 3. unbound - first argument becomes the receiver
        Function<String, String> upper = String::toUpperCase;
        System.out.println("unbound     : " + upper.apply("shout"));

        // 4. constructor
        Supplier<List<String>> maker = ArrayList::new;
        List<String> fresh = maker.get();
        fresh.add("built by ArrayList::new");
        System.out.println("constructor : " + fresh);

        System.out.println("in a stream : " +
            Stream.of("3", "1", "2").map(Integer::parseInt).sorted().collect(Collectors.toList()));
    }
}

Unbound references turn the first argument into the receiver - that is the one that confuses people.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Java 8 Course course, and every lesson in it is listed on the Java 8 Course contents page.