La repetición es la madre del aprendizaje. Aunque ya hablamos antes sobre la palabra clave switch de Java , hoy revisaremos los conceptos básicos y profundizaremos en nueva información.

Java tiene dos tipos de construcciones de cambio : la declaración de cambio y la expresión de cambio. La expresión de cambio se hizo oficial en Java 14, habiendo existido en dos variantes de "vista previa" no oficiales en las versiones 12 y 13.

Pero empecemos desde el principio. Recordemos cómo era un buen interruptor antiguo antes de la versión 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;
}

Una declaración de cambio es un conjunto de construcciones que se ejecutarán una tras otra. No te permite devolver un valor. El principal problema con el uso de una declaración de cambio es que puede agregar una cantidad infinita de expresiones de casos , y los programadores a menudo abusan de esta capacidad.

Java 12 vio la adición de una función experimental: una nueva versión de switch, no una declaración de cambio, sino una expresión de cambio, que puede generar un valor, usar programación funcional internamente y fusionar declaraciones de casos que tienen un valor común, lo que hace que el construir compacto.

En Java 12, puede reescribir el método getProductTypeByName() de la siguiente manera:


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

    };
}

Ahora el código se ve más limpio. La sintaxis de flecha de la programación funcional nos permite devolver valores sin la palabra clave break y, en general, el resultado de ejecutar el cambio ahora se puede guardar en una variable o devolver a través de la palabra clave return .

Si necesitamos no solo devolver un resultado, sino también tener varias líneas de código, entonces nuestro interruptor se vería así:


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;
}

En Java 13, la expresión de cambio todavía era una característica experimental. Para que esté disponible, al igual que en Java 12, debe usar el comando --enable-preview al compilar y ejecutar. La principal, y esencialmente única, "innovación" del conmutador en Java 13 es la palabra clave yield , que reemplazó a 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 principal diferencia entre yield y break es que break devuelve el control de ejecución de una declaración de caso , pero yield devuelve el resultado de todo el cambio , actuando como una declaración de devolución interna.

En Java 14, el operador instanceof ha cambiado y ahora se puede usar así:


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

En lugar de la forma antigua algo fea en la que no solo tenía que verificar la variable usando instanceof , sino también convertirla en un tipo específico.


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

Estos cambios son parte del proyecto Amber, cuyo objetivo es agregar soporte de coincidencia de patrones a Java.

Gracias al cambio en el operador instanceof en la versión 14 y una extensión en la versión 16, la coincidencia de patrones llegó a la versión 17 después de todo. Es cierto que existe solo como una vista previa por ahora. Puedes probarlo 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();
    };
}

En general, cada nueva versión trae más y más funciones interesantes al lenguaje, lo que hace que el desarrollo de Java sea aún más genial.