Evolución de la sentencia switch en Java.

En Java 12 se han hecho mejoras en la forma en la que se manejan los switch cases.

Uno de los objetivos contemplados en JEP 325: Switch Expressions es extender la sentencia switch para que pueda ser utilizada como una declaración o una expresión, permitiendo el comportamiento de control/alcance de flujo "tradicional" o "simplificado"

Así, se ha agregado la expresión de etiqueta: "case L -> expresión;", por la cual en lugar de tener que poner un break para los diferentes cases, se puede usar la nueva etiqueta switch para permitir que la expresión de la derecha se ejecute si la etiqueta coincide.

Esto ayuda a que el código sea más fácil de leer/comprender, además de hacer que la instrucción switch sea más rápida de escribir.

Nombre del archivo JAVA: TestSwitchColor.java


package com.marce.test;

/**
 * Test de la sentencia switch en las diferentes versiones de Java.
 *
 * @author Marce
 */

public class TestSwitchColor {

    public enum Color {
        ROJO, NARANJA, AMARILLO, CHARTREUSE, LIMA, PRIMAVERAL, AGUA, AZUR, AZUL, VIOLETA, FUCSIA, ROSA
    }

    /**
     * Formato de color en hexadecimal para css
     *
     * @param id color
     * @return color hexadecimal para css
     */
    public static String getHexColor(int nColor) {
        Color eColor = Color.values()[nColor];
        int hexColor;
        // hexColor = getColorJava4(nColor);
        // hexColor = getColorJava5(eColor);
        // hexColor = getColorJava7(eColor.name());
        hexColor = getColorJava12(eColor);
        String cHexColor = String.format("%S%06X", "#", hexColor);
        return cHexColor;
    }

    /**
     * Determina color en hexadecimal (Java hasta 1.4)
     *
     * @param id color
     * @return color hexadecimal
     */
    private static int getColorJava4(int nColor) {
        int hexColor;

        // Java hasta 1.4 se permitía utilizar la sentencia switch con los tipos de
        // datos primitivos byte, short, char, int.

        switch (nColor) {
        case 0: // ROJO
            hexColor = 0xFF0000;
            break;
        case 1: // NARANJA
            hexColor = 0xFF8000;
            break;
        case 2: // AMARILLO
            hexColor = 0xFFFF00;
            break;
        case 3: // CHARTREUSE
            hexColor = 0x80FF00;
            break;
        case 4: // LIMA
            hexColor = 0x00FF00;
            break;
        case 5: // PRIMAVERAL
            hexColor = 0x00FF80;
            break;
        case 6: // AGUA
            hexColor = 0x00FFFF;
            break;
        case 7: // AZUR
            hexColor = 0x0080FF;
            break;
        case 8: // AZUL
            hexColor = 0x0000FF;
            break;
        case 9: // VIOLETA
            hexColor = 0x8000FF;
            break;
        case 10: // FUCSIA
            hexColor = 0xFF00FF;
            break;
        case 11: // ROSA
            hexColor = 0xFF0080;
            break;
        default:
            throw new IllegalArgumentException("Java hasta 1.4 | Valor desconocido: " + nColor);
        }

        return hexColor;
    }

    /**
     * Determina color en hexadecimal (Java 5)
     *
     * @param id color
     * @return color hexadecimal
     */
    private static int getColorJava5(Color eColor) {
        int hexColor;

        // Desde Java 5 también se admiten los tipos enumerados y las clases de
        // envoltura Byte, Short, Character, Integer.

        switch (eColor) {
        case ROJO:
            hexColor = 0xFF0000;
            break;
        case NARANJA:
            hexColor = 0xFF8000;
            break;
        case AMARILLO:
            hexColor = 0xFFFF00;
            break;
        case CHARTREUSE:
            hexColor = 0x80FF00;
            break;
        case LIMA:
            hexColor = 0x00FF00;
            break;
        case PRIMAVERAL:
            hexColor = 0x00FF80;
            break;
        case AGUA:
            hexColor = 0x00FFFF;
            break;
        case AZUR:
            hexColor = 0x0080FF;
            break;
        case AZUL:
            hexColor = 0x0000FF;
            break;
        case VIOLETA:
            hexColor = 0x8000FF;
            break;
        case FUCSIA:
            hexColor = 0xFF00FF;
            break;
        case ROSA:
            hexColor = 0xFF0080;
            break;
        default:
            throw new IllegalArgumentException("Java 5 | Valor desconocido: " + eColor);
        }
        return hexColor;
    }

    /**
     * Determina color en hexadecimal (Java 7)
     *
     * @param id color
     * @return color hexadecimal
     */
    private static int getColorJava7(String cColor) {
        int hexColor;

        // En Java 7 se introdujo soporte para usar switch con String

        switch (cColor) {
        case "ROJO":
            hexColor = 0xFF0000;
            break;
        case "NARANJA":
            hexColor = 0xFF8000;
            break;
        case "AMARILLO":
            hexColor = 0xFFFF00;
            break;
        case "CHARTREUSE":
            hexColor = 0x80FF00;
            break;
        case "LIMA":
            hexColor = 0x00FF00;
            break;
        case "PRIMAVERAL":
            hexColor = 0x00FF80;
            break;
        case "AGUA":
            hexColor = 0x00FFFF;
            break;
        case "AZUR":
            hexColor = 0x0080FF;
            break;
        case "AZUL":
            hexColor = 0x0000FF;
            break;
        case "VIOLETA":
            hexColor = 0x8000FF;
            break;
        case "FUCSIA":
            hexColor = 0xFF00FF;
            break;
        case "ROSA":
            hexColor = 0xFF0080;
            break;
        default:
            throw new IllegalArgumentException("Java 7 | Valor desconocido: " + cColor);
        }
        return hexColor;
    }

    /**
     * Determina color en hexadecimal (Java 12)
     *
     * @param id color
     * @return color hexadecimal
     */
    @SuppressWarnings("preview")
    private static int getColorJava12(Color eColor) {

        // Java 12 extiende la sentencia switch para que pueda utilizarse como una
        // declaración o una expresión, y que de ambas maneras pueda usarse en el
        // formato tradicional (con break) [... :] o simplificado (sin break) [... ->].

        // Ahora lo que queremos es posible hacerlo directamente en una sentencia switch
        // de la siguiente forma.

        return switch (eColor) {
        case ROJO -> 0xFF0000;
        case NARANJA -> 0xFF8000;
        case AMARILLO -> 0xFFFF00;
        case CHARTREUSE -> 0x80FF00;
        case LIMA -> 0x00FF00;
        case PRIMAVERAL -> 0x00FF80;
        case AGUA -> 0x00FFFF;
        case AZUR -> 0x0080FF;
        case AZUL -> 0x0000FF;
        case VIOLETA -> 0x8000FF;
        case FUCSIA -> 0xFF00FF;
        case ROSA -> 0xFF0080;
        default -> throw new IllegalArgumentException("Java 12 | Valor desconocido: " + eColor);
        };

    }

}


Se probará la clase de test de la sentencia switch con una sencilla aplicación web.

Para ello se utilizará el servlet descrito seguidamente.

Nombre del archivo JAVA: TestSwitchServlet.java


package com.marce.test;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.marce.test.TestSwitchColor.Color;

/**
 * Servlet
 *
 * @author Marce
 */

@WebServlet("/")
public class TestSwitchServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * Proceso solicitud get
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setCharacterEncoding("UTF-8");
        PrintWriter html = response.getWriter();

        html.append("<!DOCTYPE html>")
            .append("<html>")
            .append("<head>")
            .append("<meta charset=\"UTF-8\">")
            .append("<title>Colores</title>")
            .append("</head>")
            .append("<body>")
            .append("<h3>Seleccione color</h3>")
            .append("<form method=\"post\">")
            .append("<select name=\"color\">");
        for (Color currCol : Color.values()) {
            String cCurrCol = currCol.name().charAt(0) + currCol.name().substring(1).toLowerCase();
            html.append("<option value=\"" + currCol.ordinal() + "\">" + cCurrCol + "</option>");
        }
        html.append("</select>")
            .append("&nbsp;")
            .append("<button type=\"submit\">Visualizar</button>")
            .append("</form>")
            .append("</body>")
            .append("</html>");
    }

    /**
     * Proceso solicitud post
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String selColor = request.getParameter("color");
        int nColor = Integer.parseInt(selColor);
        String hexColor = TestSwitchColor.getHexColor(nColor);

        response.setCharacterEncoding("UTF-8");
        PrintWriter html = response.getWriter();

        html.append("<!DOCTYPE html>")
            .append("<html>")
            .append("<head>")
            .append("<meta charset=\"UTF-8\">")
            .append("<title>Colores</title>")
            .append("</head>")
            .append("<body>")
            .append("<h3>Color en hexadecimal: " + hexColor + "</h3>")
            .append("<p style=\"background-color: " + hexColor + ";\">&nbsp;<p>")
            .append("<a href=\"" + request.getContextPath() + "\">Volver</a>")
            .append("</body>")
            .append("</html>");
    }

}

Resultado obtenido por la aplicación web de prueba.

Petición de color.
index-get
Resultado del color seleccionado.
index-post

La nueva sentencia switch se habilita compilando así: javac --enable-preview --release 12
Y en la ejecución hay que poner: java --enable-preview
Por tanto debe especificar --enable-preview en el parámetro JDK_JAVA_OPTIONS del archivo de script catalina de Tomcat.

Descargar el proyecto test-switch.

El ejemplo ha sido realizado con Java 12.0.2 y Apache Tomcat 9.0.24.

Ir al inicio de la página.