Storia della questione
Il pattern matching è una tecnica, presa in prestito da linguaggi funzionali e di scripting, che consente di controllare il tipo e estrarre dati in un solo passaggio. In Java, lo sviluppo del pattern matching è iniziato con Java 14 (funzione in anteprima), è migliorato con Java 16-17 e, nelle ultime versioni, si sta espandendo anche nello switch.
Problema
Il modo classico di controllare il tipo e fare il cast sembrava ingombrante:
if (obj instanceof String) { String s = (String) obj; ... }
Comparivano variabili non necessarie, una grande quantità di codice boilerplate e il rischio di errori di casting dei tipi.
Soluzione
Il pattern matching consente di combinare il controllo del tipo, la dichiarazione di una nuova variabile e il suo utilizzo in un'unica espressione:
if (obj instanceof String s) { System.out.println(s.length()); }
Pattern simili stanno ora apparendo nella costruzione switch, rendendo il codice più conciso e meno soggetto a errori.
Caratteristiche chiave:
Si può usare il pattern matching per classi personalizzate o solo per tipi standard?
Può essere usato per qualsiasi classe. Il pattern matching funziona per tutte le classi su cui si può applicare instanceof.
La variabile del pattern sarà accessibile al di fuori del blocco if/switch?
No, la variabile dichiarata all'interno del pattern matching è visibile solo all'interno di quel blocco in cui è stata creata (ad esempio, all'interno di un if o di un case switch).
Esempio di codice:
if (obj instanceof Integer i) { // i è visibile solo in questo blocco System.out.println(i + 10); } // Qui i non è accessibile
Si può usare il pattern matching con i generics?
Sì, in questo modo:
Object list = List.of("a", "b"); if (list instanceof List<?> l) { System.out.println(l.size()); }
Tuttavia, lavorare con tipi raw e fare il cast a tipi parametrizzati è ancora limitato a causa del type erasure.
Il team ha implementato il pattern matching in tutti i casi, inclusi DTO interni, classi di servizio e situazioni in cui il polimorfismo era sufficiente. Il codice è diventato troppo dipendente da instanceof, il ruolo delle gerarchie di classi è stato offuscato.
Vantaggi:
Svantaggi:
Nel progetto, il pattern matching è stato applicato solo per interfacce generiche, utilità ausiliarie e gestione di collezioni di tipo sconosciuto. L'architettura OOP è rimasta intatta, l'uso del pattern è avvenuto solo dove era davvero necessario.
Vantaggi:
Svantaggi: