Лямбда-выражения введены в Java 8 для более лаконичного синтаксиса реализации интерфейсов с одним методом (функциональных интерфейсов).
Функциональный интерфейс — это интерфейс с ровно одним абстрактным методом. Пример:
@FunctionalInterface interface MyAction { void perform(String s); }
Лямбда-выражение позволяет реализовать такой интерфейс:
MyAction action = (s) -> System.out.println(s); action.perform("Hello lambda!");
При использовании лямбда выражения компилятор сам понимает, какой интерфейс реализуется (target typing). Лямбды часто применяются с коллекциями:
List<String> list = Arrays.asList("one", "two", "three"); list.forEach(s -> System.out.println(s));
Вопрос: Может ли лямбда-выражение ссылаться на нестатические поля или методы внешнего класса? Какие есть ограничения по этому поводу?
Ответ: Лямбда-выражение может ссылаться на поля и методы внешнего класса, но если оно использует локальные переменные из внешнего метода, то эти переменные должны быть final или effectively final (т.е. не изменяться после первого присваивания). Например:
void doIt() { int x = 42; Runnable r = () -> System.out.println(x); // x должен быть effectively final }
Если изменить x после объявления — возникнет ошибка компиляции.
История
При использовании лямбды внутри метода была попытка изменить внешнюю локальную переменную, что привело к ошибке компиляции "Variable used in lambda expression should be final or effectively final". Разработчики потратили много времени на поиск причины, пока не вспомнили это ограничение.
История
В одном проекте использовали собственные интерфейсы для лямбд, но забыли аннотировать их
@FunctionalInterface. После рефакторинга в интерфейс добавили второй метод и проект перестал компилироваться. Это вызвало неожиданные ошибки, которые трудно было отловить.
История
Попытка сериализовать объект, который содержал поле с лямбда-выражением, привела к тому, что сериализация/десериализация не работала корректно — лямбда не сериализуется по умолчанию. Важно помнить, что если лямбда содержит неконсистентные зависимости — при передаче по сети появятся ошибки.