Enum en Java: valores con datos, métodos y switch

Un enum en Java es un tipo con una lista cerrada de valores: los días de la semana, los estados de un pedido, los tamaños de un café. Y es mucho más que una lista de constantes: cada valor puede llevar datos y métodos, y el compilador comprueba que no se te olvide ninguno.

Un enum con datos

import java.util.EnumMap;
import java.util.EnumSet;

enum Tamano {
    CHICO("8 oz", 35), MEDIANO("12 oz", 45), GRANDE("16 oz", 55);

    private final String onzas;
    private final int precio;

    Tamano(String onzas, int precio) { this.onzas = onzas; this.precio = precio; }

    String etiqueta() { return name().charAt(0) + name().substring(1).toLowerCase() + " (" + onzas + ")"; }
    int precio() { return precio; }
}

enum Estado { RECIBIDO, PREPARANDO, LISTO, ENTREGADO }

String aviso(Estado e) {
    return switch (e) {
        case RECIBIDO -> "Tu pedido llegó";
        case PREPARANDO -> "Lo estamos preparando";
        case LISTO -> "Pasa a recogerlo";
        case ENTREGADO -> "¡Buen provecho!";
    };
}

void main() {
    for (Tamano t : Tamano.values()) IO.println(t.ordinal() + " " + t.etiqueta() + ": $" + t.precio());

    Tamano elegido = Tamano.valueOf("mediano".toUpperCase());
    IO.println("elegido: " + elegido + ", ¿más caro que CHICO? " + (elegido.compareTo(Tamano.CHICO) > 0));

    IO.println(aviso(Estado.LISTO));

    var pedidos = new EnumMap<Estado, Integer>(Estado.class);
    pedidos.merge(Estado.LISTO, 1, Integer::sum);
    pedidos.merge(Estado.RECIBIDO, 3, Integer::sum);
    IO.println(pedidos);

    EnumSet<Estado> abiertos = EnumSet.range(Estado.RECIBIDO, Estado.LISTO);
    IO.println("abiertos: " + abiertos);

    try {
        Tamano.valueOf("EXTRA");
    } catch (IllegalArgumentException e) {
        IO.println(e.getMessage());
    }
}
salida0 Chico (8 oz): $35
1 Mediano (12 oz): $45
2 Grande (16 oz): $55
elegido: MEDIANO, ¿más caro que CHICO? true
Pasa a recogerlo
{RECIBIDO=3, LISTO=1}
abiertos: [RECIBIDO, PREPARANDO, LISTO]
No enum constant Enums.Tamano.EXTRA

Lo que conviene saber

  • Cada valor es un objeto único, así que se comparan con == sin problema (al contrario que los String o los Integer).
  • values() devuelve todos los valores en el orden en que se declararon, y ordinal() la posición. No guardes el ordinal() en una base de datos: si alguien inserta un valor en medio, cambian todos. Guarda el name().
  • valueOf convierte desde texto y lanza IllegalArgumentException si no existe, con un mensaje que dice exactamente qué constante buscó.
  • En un switch con flechas que cubre todos los valores, no hace falta default: si añades un estado nuevo, el compilador te obliga a tratarlo.
  • EnumMap y EnumSet son un mapa y un conjunto optimizados para enums: más rápidos que un HashMap y ordenados según la declaración.

Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.