ProgrammazioneSviluppatore Java

Spiega come funzionano le espressioni lambda e le interfacce funzionali in Java. Quali errori possono verificarsi in caso di uso scorretto?

Supera i colloqui con l'assistente IA Hintsage

Risposta

Le espressioni lambda sono state introdotte in Java 8 per una sintassi più concisa nell'implementazione di interfacce con un solo metodo (interfacce funzionali).

Un'interfaccia funzionale è un'interfaccia con esattamente un metodo astratto. Esempio:

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

Un'espressione lambda consente di implementare tale interfaccia:

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

Quando si utilizza un'espressione lambda, il compilatore comprende automaticamente quale interfaccia viene implementata (target typing). Le lambda sono spesso utilizzate con le collezioni:

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

Domanda insidiosa

Domanda: Un'espressione lambda può riferirsi a campi o metodi non statici della classe esterna? Quali sono le limitazioni a riguardo?

Risposta: Un'espressione lambda può riferirsi ai campi e metodi della classe esterna, ma se utilizza variabili locali del metodo esterno, queste variabili devono essere final o effectively final (cioè non devono cambiare dopo la prima assegnazione). Esempio:

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

Se si modifica x dopo la dichiarazione, si verificherà un errore di compilazione.

Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze del tema


Storia

Durante l'uso di una lambda all'interno di un metodo, si è cercato di modificare una variabile locale esterna, il che ha portato a un errore di compilazione "Variable used in lambda expression should be final or effectively final". Gli sviluppatori hanno impiegato molto tempo per trovare la causa, fino a quando non si sono ricordati di questa limitazione.


Storia

In un progetto sono state utilizzate interfacce personalizzate per le lambda, ma si è dimenticato di annotarle con @FunctionalInterface. Dopo il refactoring, è stato aggiunto un secondo metodo all'interfaccia e il progetto ha smesso di compilare. Questo ha causato errori imprevisti, difficili da rilevare.


Storia

Tentare di serializzare un oggetto che conteneva un campo con un'espressione lambda ha portato al fatto che la serializzazione/deserializzazione non funzionava correttamente: la lambda non viene serializzata per impostazione predefinita. È importante ricordare che se la lambda contiene dipendenze inconsistenti, si verificheranno errori durante la trasmissione in rete.