Зачем лямбде нужно захватывать включающий экземпляр при обращении к последнему полю String?

Это основано наэтот вопрос, Рассмотрим этот пример, где метод возвращаетConsumer на основе лямбда-выражения:

public class TestClass {
    public static void main(String[] args) {
        MyClass m = new MyClass();
        Consumer<String> fn = m.getConsumer();

        System.out.println("Just to put a breakpoint");
    }
}

class MyClass {
    final String foo = "foo";

    public Consumer<String> getConsumer() {
        return bar -> System.out.println(bar + foo);
    }
}

Как мы знаем, не рекомендуется ссылаться на текущее состояние внутри лямбды при выполнении функционального программирования. Одна из причин заключается в том, что лямбда будет захватывать включающий экземпляр, который не будет собирать мусор, пока сама лямбда не выйдет из области видимости.

Однако в этом конкретном сценарии, связанном сfinal Строки, кажется, компилятор мог просто заключить константу (final) строкаfoo (из постоянного пула) в возвращаемой лямбде, вместо того, чтобы заключать целоеMyClass экземпляр, как показано ниже при отладкеSystem.out.println). Связано ли это с тем, как лямбды компилируются в специальныеinvokedynamic байткод?

Ответы на вопрос(1)

Ваш ответ на вопрос