La ripetizione è la madre dell'apprendimento. Sebbene abbiamo già parlato in precedenza della parola chiave switch di Java , oggi rivedremo le basi e scaveremo in alcune nuove informazioni.

Java ha due tipi di costrutti switch : l'istruzione switch e l'espressione switch. L'espressione switch è diventata ufficiale in Java 14, essendo esistita in due varianti non ufficiali di "anteprima" nelle versioni 12 e 13.

Ma partiamo dall'inizio. Ricordiamo come appariva un buon vecchio switch prima della versione 12:

public String getProductTypeByName(String product) {
    String productType = "";

    switch (product) {
        case "Apple":
            productType = "Fruit";
            break;

        case "Peach":
            productType = "Fruit";
            break;

        case "Raspberry":
            productType = "Berry";
            break;

        case "Cherry":
            productType = "Berry";
            break;

        case "Tomato":
            productType = "Vegetable";
            break;

        default:
            productType = "other";
            break;
    }

    return productType;
}

Un'istruzione switch è un insieme di costrutti che verranno eseguiti uno dopo l'altro. Non ti consente di restituire un valore. Il problema principale con l'utilizzo di un'istruzione switch è che è possibile aggiungere un numero infinito di espressioni case e questa capacità viene spesso abusata dai programmatori.

Java 12 ha visto l'aggiunta di una funzionalità sperimentale: una nuova versione di switch — non un'istruzione switch, ma un'espressione switch — che può produrre un valore, utilizzare internamente la programmazione funzionale e unire istruzioni case che hanno un valore comune, rendendo così il costruire compatto.

In Java 12, puoi riscrivere il metodo getProductTypeByName() come segue:

public String getProductTypeByName(String product) {
    return switch (product) {
        case "Apple", "Peach" -> "Fruit";
        case "Raspberry", "Cherry" -> "Berry";
        case "Tomato" -> "Vegetable";
        default -> "other";

    };
}

Ora il codice sembra più pulito. La sintassi della freccia della programmazione funzionale ci consente di restituire valori senza la parola chiave break e, in generale, il risultato dell'esecuzione dello switch ora può essere salvato in una variabile o restituito tramite la parola chiave return .

Se abbiamo bisogno non solo di restituire un risultato, ma anche di avere più righe di codice, il nostro switch sarà simile a questo:

public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is a Fruit");
            break "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            break "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetable");
            break "Vegetable";
        }
        default -> {
            break "other";
        }

    };
     return result;
}

In Java 13, l'espressione switch era ancora una funzionalità sperimentale. Per renderlo disponibile, proprio come in Java 12, è necessario utilizzare il comando --enable-preview durante la compilazione e l'esecuzione. La principale, ed essenzialmente unica, "innovazione" dello switch in Java 13 è la yield parola chiave, che ha sostituito break .

public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is a Fruit");
            yield "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            yield "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetable");
            yield "Vegetables";
        }
        default -> {
            System.out.println("Other");
            yield "other";
        }

    };
    return result;
}

La differenza principale tra yield e break è che break restituisce il controllo dell'esecuzione da un'istruzione case , ma yield restituisce il risultato dell'intero switch , agendo come un'istruzione return interna .

In Java 14, l' operatore instanceof è cambiato e ora può essere utilizzato in questo modo:

if (o instanceof String s) {
s.toLowerCase();
}

Invece del vecchio modo un po 'brutto in cui dovevi non solo controllare la variabile usando instanceof , ma anche lanciarla su un tipo specifico.

if(s instanceof String) {
((String) s).toLowerCase();
}

Queste modifiche fanno parte del progetto Amber, che mira ad aggiungere il supporto per il pattern matching a Java.

Grazie alla modifica dell'operatore instanceof nella versione 14 ea un'estensione nella versione 16, il pattern matching è arrivato alla versione 17 dopo tutto. È vero, esiste solo come anteprima per ora. Puoi provarlo con --enable-preview :

public String getObjectType(Object object) {
    return switch (object) {
        case Integer i -> "Integer";
        case Long l -> "Long";
        case String s -> "String";
        default -> object.toString();
    };
}

In generale, ogni nuova versione introduce funzionalità sempre più interessanti nel linguaggio, il che rende lo sviluppo Java ancora più interessante.