Справочник по методу ↔ лямбда-эквивалент

Если вы поместите курсор на ссылку на метод связанного получателя, например str::toUpperCase в IntelliJ IDEA, и нажмете Alt + Enter, он предложит заменить его лямбдой. Если вы продолжите, он изменит ссылку на метод на () -> str.toUpperCase(). Вероятно, это ошибка в IntelliJ IDEA, хотя я подозреваю, что это обычная ошибка и в других IDE. Почему? Что ж, это не всегда равнозначно. Возьмите следующую маленькую загадку. Что дает следующий код?

import java.util.function.Supplier;

public class Scratch {

    private static String str;

    public static void main(String[] args) {
        str = "a";
        Supplier<String> methodref = str::toUpperCase;
        Supplier<String> lambda = () -> str.toUpperCase();

        str = "b";
        System.out.println(methref.get());
        System.out.println(lambda.get());
    }
}

Этот код показывает, что ссылка на метод и лямбда не эквивалентны. Код печатает разные значения в каждой строке: «a» и «b». Мой вопрос: каков правильный лямбда-эквивалент этого типа ссылки на метод?


person DodgyCodeException    schedule 16.10.2018    source источник
comment
Что касается ошибки IntelliJ, то это только то, что она должна указывать «(может изменить семантику)», как при выполнении наоборот. Вы должны сообщить об этом.   -  person Didier L    schedule 16.10.2018


Ответы (1)


Для вашей настройки поставщика ответ: нет эквивалента.

Когда вы пишете:

str = "a";
Supplier<String> methodref = str::toUpperCase;

он буквально становится "a"::toUpperCase (который фактически компилируется).

person Doe Johnson    schedule 16.10.2018