Почему лямбда может захватывать только effectively final локальные переменные?
Лямбда захватывает значение локальной переменной (копию), а не ячейку: локальная переменная живёт в кадре стека и исчезает вместе с методом, а лямбда может жить дольше и выполняться в другом потоке. Разрешить изменения — значит молча расходиться оригиналу и копии.
- Поля объекта и статические поля менять можно — ограничение только на локальные
- Нужен изменяемый счётчик — AtomicInteger или массив из одного элемента (хак)
- Effectively final — переменная не переприсваивается после инициализации, даже без слова final
А ещё Изменять общее состояние из лямбды в parallel stream — гонка
Подробно
Локальные переменные живут на стеке и исчезают с кадром метода, поэтому лямбда захватывает их значение, а не саму ячейку. Разрешить мутацию значило бы менять копию незаметно для оригинала. Поля объекта и статические поля менять можно — ограничение только на локалки. Нужен изменяемый счётчик — берут поле, массив-холдер или Atomic.
Что хотят услышать
- Захват значения и время жизни кадра.
- Различие локальных переменных и полей.
Частые ошибки
- Пытаться инкрементировать локальную переменную из лямбды.
- Считать, что ограничение касается и полей объекта.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Это ограничение синтаксиса, обходится словом var
- ✓Захватывается копия значения, и мутация привела бы к рассинхрону
- ✗Потому что лямбды всегда выполняются в другом потоке и не видят стек метода
- ✗Лямбда вообще не может читать локальные переменные
Что спросят дальше
- Как обойти запрет через holder/Atomic?
- Что значит effectively final?
Разбор темы
- Лямбды и функциональные интерфейсы
SAM-интерфейсы, лямбда против анонимного класса, замыкания и effectively final, ссылки на методы и стандартные интерфейсы.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.