Wyrażenia lambda zostały wprowadzone w Javie 8 dla bardziej zwięzłej składni realizacji interfejsów z jedną metodą (interfejsów funkcjonalnych).
Interfejs funkcjonalny to interfejs z dokładnie jedną metodą abstrakcyjną. Przykład:
@FunctionalInterface interface MyAction { void perform(String s); }
Wyrażenie lambda pozwala zaimplementować taki interfejs:
MyAction action = (s) -> System.out.println(s); action.perform("Hello lambda!");
Przy użyciu wyrażenia lambda kompilator sam rozumie, jaki interfejs jest implementowany (target typing). Lambdy są często stosowane z kolekcjami:
List<String> list = Arrays.asList("one", "two", "three"); list.forEach(s -> System.out.println(s));
Pytanie: Czy wyrażenie lambda może odnosić się do niestatycznych pól lub metod klasy zewnętrznej? Jakie są ograniczenia w tym zakresie?
Odpowiedź: Wyrażenie lambda może odnosić się do pól i metod klasy zewnętrznej, ale jeśli używa lokalnych zmiennych z metody zewnętrznej, to te zmienne muszą być final lub effectively final (tzn. nie mogą być zmieniane po pierwszym przypisaniu). Na przykład:
void doIt() { int x = 42; Runnable r = () -> System.out.println(x); // x musi być effectively final }
Jeśli zmienisz x po zadeklarowaniu — wystąpi błąd kompilacji.
Historia
Przy użyciu lambdy wewnątrz metody podjęto próbę zmiany zewnętrznej zmiennej lokalnej, co doprowadziło do błędu kompilacji "Variable used in lambda expression should be final or effectively final". Programiści spędzili dużo czasu na szukaniu przyczyny, aż przypomnieli sobie to ograniczenie.
Historia
W jednym projekcie używano własnych interfejsów dla lambd, ale zapomniano oznaczyć je
@FunctionalInterface. Po refaktoryzacji do interfejsu dodano drugą metodę i projekt przestał się kompilować. Spowodowało to nieoczekiwane błędy, które trudno było wykryć.
Historia
Próba serializacji obiektu, który zawierał pole z wyrażeniem lambda, doprowadziła do tego, że serializacja/deserializacja nie działała poprawnie — lambda nie jest serializowana domyślnie. Ważne jest, aby pamiętać, że jeśli lambda zawiera niespójne zależności — podczas przesyłania przez sieć pojawią się błędy.