Установите значение локальной переменной внутри лямбды - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть следующий код:

  public void visitStrAttribute(String attributeName, Consumer<String> attributeConsumer) {
    IntConsumer intConsumer;
    int stringByteArrayLength = 0;
    visitIntAttribute("", (IntValue) -> stringByteArrayLength = IntValue);
    attributeConsumer
        .accept(new String(readInputStream(stringByteArrayLength), StandardCharsets.UTF_8));
  }

Мне нужно установить stringByteArrayLength внутри лямбды, но появляется сообщение об ошибке, и оно говорит мне Local variable stringByteArrayLength defined in an enclosing scope must be final or effectively final.

Как мнеисправить это?

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

У вас есть две альтернативы:

  • Создайте класс с таким атрибутом, чтобы объект из него был конечным, но не переменные экземпляра
  • Сделать область видимости переменной переменной (будьте осторожны с многопоточностью)

Эти решения работают, но, возможно, это не лучший вариант, поэтому для вдохновения посмотрите: Лямбды: локальные переменные должны быть окончательными, переменные экземпляра не

0 голосов
/ 11 сентября 2018

Создайте упаковщик:

private static class Integerwrapper {
    private int num;

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

и используйте его как int.

edit:

Вы можете использовать упаковщик int как: AtomicInteger

0 голосов
/ 11 сентября 2018

Одно из решений состоит в том, чтобы сделать вашу переменную окончательным массивом с одним элементом и изменить элемент внутри него, например так:

final int[] stringByteArrayLength = {0};
visitIntAttribute("", (IntValue) -> stringByteArrayLength[0] = IntValue);

Хотя я не считаю это лучшей практикой. Я бы скорее вернул новое измененное значение, чем изменил бы его.

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