Что может стоять слева от оператора ссылки на метод (::) в Java?

«Что может стоять слева от оператора ссылки на метод (::) в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Слева от оператора :: указывается цель ссылки. Возможные варианты:

  1. Имя класса — для ссылки на статический метод.

    Function<String, Integer> parser = Integer::parseInt; // Статический метод
  2. Ссылка на объект (или выражение, её возвращающее) — для ссылки на метод экземпляра конкретного объекта.

    String prefix = "ERROR-";
    Function<String, String> formatter = prefix::concat; // Метод конкретного объекта
  3. Имя класса — для ссылки на конструктор.

    Supplier<List<String>> supplier = ArrayList::new; // Конструктор
  4. Имя класса — для ссылки на метод экземпляра, который будет вызван у объекта, переданного позже (первый параметр становится целевым объектом).

    Function<String, Integer> lengthGetter = String::length; // length() будет вызван у строки
    BiPredicate<String, String> checker = String::equals; // equals() вызван у первой строки

Практический пример с forEach:

List<String> names = Arrays.asList("Alice", "Bob");

// Ссылка на статический метод класса
names.forEach(System.out::println); // println - статический? Нет! Это пример 2.
// System.out — это статическое поле (объект PrintStream), поэтому это ссылка на метод конкретного объекта.

// Ссылка на метод экземпляра произвольного объекта (пример 4)
names.stream().map(String::toUpperCase).forEach(System.out::println);
// toUpperCase() будет вызван для каждого элемента потока.

Итог: Слева от :: может быть класс (для статических методов, конструкторов или методов экземпляра) или ссылка на существующий объект.