Есть ли способ изменить значение, захваченное Java Lambda - PullRequest
0 голосов
/ 04 мая 2018

как то так:

    Integer value = 3;
    Consumer<Integer> consumer = input -> {
        value = value * 2;
    };
    consumer.accept(100);
    System.out.println(value);

Спасибо! [Решено]

    AtomicInteger value = new AtomicInteger(3);
    Consumer<Integer> consumer = input -> {
        value.getAndAdd(5); // 8
        System.out.println(value.get());
    };
    consumer.accept(100);
    System.out.println(value.get()); // 8

также спасибо за ответ Умера Фарука Изменение локальной переменной изнутри лямбда

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Таким образом, поскольку компилятор Java разрешает доступ к окончательным ссылкам или ссылкам на элементы в лямбда-выражениях или анонимных внутренних классах, ответ - нет. Однако вы можете (как вы, кажется, нашли) изменить состояние внутри окончательной ссылки.

Вы нашли обходной путь с AtomicInteger, который работает в вашем конкретном случае, когда вы изменяете Integer. Размещение вашей ссылки в окончательном массиве с одним значением будет работать для всего, хотя. Это не очень красиво, но если вы используете IntelliJ, он предложит вам сделать это изменение, если вы попытаетесь изменить конечное состояние в такой ситуации.

Вот пример:

final int[] value = { 3 };
Consumer<Integer> consumer = input -> {
    value[0] = value[0] * 2;
};
consumer.accept(100);
System.out.println(value[0]);
0 голосов
/ 04 мая 2018

Нет, это невозможно.

JLS 15,27.2 говорит:

Любая локальная переменная, формальный параметр или параметр исключения, используемые, но не объявленные в лямбда-выражении, должны быть либо объявлены окончательными, либо фактически окончательными (§4.12.4), либо при попытке использования возникает ошибка времени компиляции.

Поскольку вы используете value в лямбде, но объявляете его вне лямбды, оно должно быть окончательным или эффективно окончательным. Это означает, что вы не можете присвоить ему значение более одного раза.

Конечно, если бы value был изменяемым объектом (например, AtomicInteger), то вы могли бы изменить его. Сама ссылка value не изменится, но объект, на который она ссылается, будет изменен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...