Зачем лямбде нужно захватывать включающий экземпляр при обращении к последнему полю 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
байткод?