ProgrammatieJava ontwikkelaar

Leg uit hoe lambda-expressies en functionele interfaces werken in Java. Welke fouten kunnen optreden bij verkeerd gebruik?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Lambda-expressies zijn geïntroduceerd in Java 8 voor een meer beknopte syntaxis bij de implementatie van interfaces met één methode (functionele interfaces).

Een functionele interface is een interface met precies één abstracte methode. Voorbeeld:

@FunctionalInterface interface MyAction { void perform(String s); }

Een lambda-expressie maakt het mogelijk om zo'n interface te implementeren:

MyAction action = (s) -> System.out.println(s); action.perform("Hello lambda!");

Bij het gebruik van een lambda-expressie begrijpt de compiler zelf welke interface er geïmplementeerd wordt (target typing). Lambda's worden vaak gebruikt met collecties:

List<String> list = Arrays.asList("one", "two", "three"); list.forEach(s -> System.out.println(s));

Misleidende vraag

Vraag: Kan een lambda-expressie verwijzen naar niet-statische velden of methoden van de externe klasse? Wat zijn de beperkingen in dit verband?

Antwoord: Een lambda-expressie kan verwijzen naar velden en methoden van de externe klasse, maar als het lokale variabelen uit de externe methode gebruikt, moeten deze variabelen final of effectively final zijn (d.w.z. ze mogen niet veranderen na de eerste toewijzing). Bijvoorbeeld:

void doIt() { int x = 42; Runnable r = () -> System.out.println(x); // x moet effectively final zijn }

Als x na de declaratie wordt gewijzigd, ontstaat er een compilatiefout.

Voorbeelden van echte fouten door onwetendheid over de nuances van het onderwerp


Verhaal

Bij het gebruik van een lambda binnen een methode was er een poging om een externe lokale variabele te wijzigen, wat leidde tot de compilatiefout "Variable used in lambda expression should be final or effectively final". Ontwikkelaars hebben veel tijd besteed aan het zoeken naar de oorzaak totdat ze zich deze beperking herinnerden.


Verhaal

In een project werden eigen interfaces voor lambda's gebruikt, maar ze vergaten deze te annoteren met @FunctionalInterface. Na refactoren werd er een tweede methode aan de interface toegevoegd en het project compileerde niet meer. Dit leidde tot onverwachte fouten die moeilijk te traceren waren.


Verhaal

Een poging om een object te serialiseren dat een veld met een lambda-expressie bevatte, resulteerde in het niet correct werken van de serialisatie/deserialisatie — een lambda wordt standaard niet serialiseerbaar. Het is belangrijk om te onthouden dat als de lambda inconsistente afhankelijkheden bevat, er fouten optreden bij overdracht over het netwerk.