Как в лямбде изменить внешнюю локальную переменную?

Изменить локальную переменную, в ламбде, стандартными методами невозможно, потому, что локальная переменная должны быть effectively final, то есть не должна изменяться после объявления.

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

Для того, чтобы решить данную проблему в лямбда-выражение помещается копия требуемой локальной переменной, которая независима от оригинала. Но в таком случае копия и локальный оригинал будут разными, независящими друг от друга переменными, а это может привести к сложностям, из-за возможности использования неактуальных, устаревших значений. Чтобы значение было всегда актуально оно не должно меняться.

Чтобы изменить локальную переменную нужно отправить её в кучу. Чтобы это сделать, можно использовать обёртку, например, одноэлементный массив или класс с нужной переменной. Однако это не решает проблему с актуальностью. Поэтому, при использовании многопоточности, рекомендуется уделить внимание синхронизации работы потоков с данной переменной.

void doLater(Runnable r){
  new Thread(() -> {
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {}
  }).start();
}

void main() {
  int i = 0;
  doLater(() -> {
    // Ошибка - к этому моменту переменная может быть 0, 1, или перестать существовать.
    i += 42;
   });
   i++; // Было бы здесь 43 или 1 - неизвестно.
}

void hackO {
  int[] i = {0}; 
  doLater(() -> {
    // Теперь это компилируется, но поведение непредсказуемо – опасно
    i[0] += 42;
  });
  i[0]++;
}

Бесплатные Telegram-боты для обучения

Практика с проверкой кода и помощью ИИ-ментора

AndroidSprint AI Mentor

Проверяет Pull Request'ы в GitHub, проводит тестовые собеседования с голосом и таймером, помогает разбираться с кодом 24/7

Попробовать ИИ-ментора →

KotlinSprint Bot

22 урока Kotlin, 220 тестов, 120 практических задач с код-ревью

Начать обучение Kotlin →

AndroidSprint Bot

Тесты по Android SDK, Jetpack Compose, архитектуре приложений

Тесты по Android →

Бесплатная диагностика с сениор разработчиком

Запишитесь на консультацию — перезвоним в рабочие часы

Или свяжитесь удобным способом

Вам также может быть интересно

Узнать подробнее
Курс AndroidSprint

Глубокое обучение Android разработке с 0 до получения оффера. Только персональная практика с гарантией получения продуктового опыта.

Курс AndroidSprint - Глубокое <strong>обучение Android разработке с 0 до получения оффера</strong>. Только персональная практика с гарантией получения продуктового опыта.
Узнать подробнее
Узнать подробнее
Практикум по Kotlin

Изучение Котлин с 0 для профессиональной разработки. Личный ментор и разбор кода задач через git-flow.

Практикум по Kotlin - Изучение Котлин <strong>с 0 для профессиональной разработки</strong>. Личный ментор и разбор кода задач через git-flow.
Узнать подробнее
Узнать подробнее
Бесплатные уроки по Kotlin разработке

Самостоятельное освоение базы по языку для дальнейшего развития в Android/back-end разработке или в автотестах.

Бесплатные уроки по Kotlin разработке - <span>Самостоятельное освоение базы по языку для дальнейшего развития в Android/back-end разработке или в автотестах.</span>
Узнать подробнее
Узнать подробнее
Onboarding в разработку

Полное обучение Android разработке с нуля до получения оффера. Делаем упор на практику и обратную связь

Onboarding в разработку - <span>Полное обучение Android разработке с нуля до получения оффера. Делаем упор на практику и обратную связь</span>
Узнать подробнее
Узнать подробнее
Обучающий Kotlin телеграм бот (с тестами)

Ваш основной инструмент для изучения основ языка. Бесплатные тесты и практика внутри.

Обучающий Kotlin телеграм бот (с тестами) - Ваш основной <span>инструмент для изучения основ языка.</span> Бесплатные тесты и практика внутри.
Узнать подробнее
Узнать подробнее
Бесплатные уроки по Android разработке

Самостоятельное обучение разработке Андроид приложений. Понятные видеоуроки с разжеванными примерами.

Бесплатные уроки  по Android разработке - Самостоятельное <span>обучение разработке Андроид приложений.</span> Понятные видеоуроки с разжеванными примерами.
Узнать подробнее
Узнать подробнее
Курс по UI/Unit тестированию

Для ручных тестировщиков, которые готовы осваивать автотесты с использованием актуального стека технологий. [в разработке]

Курс по UI/Unit тестированию - Для ручных тестировщиков, которые <span>готовы осваивать автотесты</span> с использованием актуального стека технологий. [в разработке]
Узнать подробнее
Узнать подробнее
Обучающий Android телеграм бот (с тестами)

Бесплатные теоретические тесты для самопроверки. А также информер на практических спринтах по Android.

Обучающий Android телеграм бот (с тестами) - Бесплатные <span>теоретические тесты для самопроверки.</span> А также информер на практических спринтах по Android.
Узнать подробнее
ИИ-ментор код-ревью и голосовые собесы
Открыть