• В какой момент лямбда в java считывает локальную переменную?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Java
    Седой и строгий
    Компилятор преобразовывает лямбды в анонимные классы. Эти классы могут менять поля объемлющего объекта или других объектов, на которые имеют ссылки. Но передаваемые в лямбды локальные переменные должны быть неизменяемыми, так как замыкания в Java эмулируются созданием в анонимном классе поля, захватывающего значение замыкаемой переменной. Убедиться в этом просто. Скомпилируем класс

    public class Main {
        public static void main(String[] args) throws Exception {
            String value = "Test";
            Supplier<String> lambda = () -> value;
        }
    }

    и запустим с параметром -Djdk.internal.lambda.dumpProxyClasses=., чтобы Java сохранила сгенерированный анонимный класс. Заглянем внутрь этого класса

    $ javap -p Main$$Lambda$1
    final class Main$$Lambda$1 implements java.util.function.Supplier {
      private final java.lang.String arg$1;  // Захваченная переменная value
      private Main$$Lambda$1(java.lang.String);
      private static java.util.function.Supplier get$Lambda(java.lang.String);
      public java.lang.Object get();
    }


    Об этом можно почитать у Брайана Гетца в "State of the Lambda: Variable capture".
    Ответ написан
    1 комментарий