Ir al contenido principal

Enumeraciones en Java

Introducción

Las enumeraciones (o enum) son un tipo especial de clase en Java que nos permite definir un conjunto de constantes con nombre, creando así un tipo de dato personalizado con un número limitado de valores posibles. Introducidas en Java 5, las enumeraciones solucionan elegantemente problemas comunes en la programación como la representación de conjuntos fijos de valores (días de la semana, meses del año, estados de un proceso, etc.).

Las enumeraciones en Java son mucho más potentes que en otros lenguajes de programación, ya que no son simples listas de constantes enteras, sino clases completas que pueden tener campos, métodos y constructores. Esta característica nos brinda una forma segura y eficiente de modelar conceptos del mundo real que tienen un conjunto finito y predeterminado de valores.

Creación de enumeraciones básicas

La forma más simple de crear una enumeración es usando la palabra clave enum seguida del nombre de la enumeración y una lista de constantes.

public enum DiaSemana {
    LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
}

Por convención, los valores de la enumeración se escriben en mayúsculas, como es habitual con las constantes en Java.

Uso de enumeraciones

Veamos cómo podemos utilizar esta enumeración en un programa:

public class PruebaEnum {
    public static void main(String[] args) {
        // Declaración de una variable de tipo DiaSemana
        DiaSemana hoy = DiaSemana.MIERCOLES;
        
        // Uso en una estructura switch
        switch (hoy) {
            case LUNES:
                System.out.println("Inicio de semana laboral");
                break;
            case MARTES:
            case MIERCOLES:
            case JUEVES:
                System.out.println("Mitad de semana laboral");
                break;
            case VIERNES:
                System.out.println("Fin de semana laboral");
                break;
            case SABADO:
            case DOMINGO:
                System.out.println("Fin de semana");
                break;
        }
        
        // Comparación directa
        if (hoy == DiaSemana.MIERCOLES) {
            System.out.println("Es miércoles");
        }
    }
}

Observa que en la estructura switch, no necesitamos calificar las constantes con el nombre de la enumeración.

Métodos integrados de las enumeraciones

Todas las enumeraciones en Java heredan implícitamente de la clase java.lang.Enum, lo que les proporciona varios métodos útiles:

public class MetodosEnum {
    public static void main(String[] args) {
        // Obtener nombre como cadena
        String nombre = DiaSemana.LUNES.name();
        System.out.println("Nombre: " + nombre); // Imprime: Nombre: LUNES
        
        // Obtener posición ordinal (comienza en 0)
        int orden = DiaSemana.MIERCOLES.ordinal();
        System.out.println("Orden de MIERCOLES: " + orden); // Imprime: Orden de MIERCOLES: 2
        
        // Convertir cadena a enum
        DiaSemana dia = DiaSemana.valueOf("VIERNES");
        System.out.println("Dia: " + dia); // Imprime: Dia: VIERNES
        
        // Obtener todos los valores
        DiaSemana[] dias = DiaSemana.values();
        System.out.println("Días de la semana:");
        for (DiaSemana d : dias) {
            System.out.println(d);
        }
    }
}

Enumeraciones con propiedades y métodos

Una de las características más potentes de las enumeraciones en Java es que pueden incluir campos, constructores y métodos, convirtiéndolas prácticamente en clases completas:

public enum Planeta {
    MERCURIO(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    TIERRA(5.976e+24, 6.37814e6),
    MARTE(6.421e+23, 3.3972e6),
    JUPITER(1.9e+27, 7.1492e7),
    SATURNO(5.688e+26, 6.0268e7),
    URANO(8.683e+25, 2.5559e7),
    NEPTUNO(1.024e+26, 2.4746e7);

    // Campos
    private final double masa;   // en kilogramos
    private final double radio;  // en metros
    
    // Constante gravitacional universal
    private static final double G = 6.67300E-11;
    
    // Constructor
    Planeta(double masa, double radio) {
        this.masa = masa;
        this.radio = radio;
    }
    
    // Métodos
    public double getMasa() {
        return masa;
    }
    
    public double getRadio() {
        return radio;
    }
    
    // Calcular la gravedad superficial
    public double gravedadSuperficial() {
        return G * masa / (radio * radio);
    }
    
    // Calcular el peso en este planeta
    public double calcularPeso(double masaObjeto) {
        return masaObjeto * gravedadSuperficial();
    }
}

Ahora podemos usar esta enumeración para calcular el peso de un objeto en diferentes planetas:

public class PruebaEnumPlaneta {
    public static void main(String[] args) {
        double peso = 70;  // peso en kg en la Tierra
        double masa = peso / Planeta.TIERRA.gravedadSuperficial();
        
        for (Planeta planeta : Planeta.values()) {
            System.out.printf("Tu peso en %s es %.2f kg%n", 
                              planeta, planeta.calcularPeso(masa));
        }
    }
}

Enumeraciones e interfaces

Las enumeraciones pueden implementar interfaces, lo que permite crear comportamientos polimórficos:

interface Describible {
    String getDescripcion();
}

public enum NivelEstudio implements Describible {
    PRIMARIA("Educación básica inicial"),
    SECUNDARIA("Educación media obligatoria"),
    BACHILLERATO("Educación preuniversitaria"),
    UNIVERSITARIO("Educación superior"),
    POSGRADO("Especialización académica");
    
    private final String descripcion;
    
    NivelEstudio(String descripcion) {
        this.descripcion = descripcion;
    }
    
    @Override
    public String getDescripcion() {
        return descripcion;
    }
}

Enumeraciones anidadas

También podemos definir enumeraciones dentro de clases:

public class Empresa {
    public enum Departamento {
        VENTAS, MARKETING, DESARROLLO, RECURSOS_HUMANOS, FINANZAS
    }
    
    private String nombre;
    private Departamento departamento;
    
    public Empresa(String nombre, Departamento departamento) {
        this.nombre = nombre;
        this.departamento = departamento;
    }
    
    // Resto de la clase...
}

// Uso:
Empresa.Departamento dept = Empresa.Departamento.DESARROLLO;

Enumeraciones y patrones de diseño

Las enumeraciones son especialmente útiles en el patrón de diseño Singleton y el patrón Estrategia:

public enum ConfiguracionSingleton {
    INSTANCIA;
    
    private String urlBaseDatos;
    private int puerto;
    
    // Constructor privado por defecto
    private ConfiguracionSingleton() {
        // Inicialización
        urlBaseDatos = "jdbc:mysql://localhost:3306/db";
        puerto = 8080;
    }
    
    public String getUrlBaseDatos() {
        return urlBaseDatos;
    }
    
    public int getPuerto() {
        return puerto;
    }
}

// Uso:
String url = ConfiguracionSingleton.INSTANCIA.getUrlBaseDatos();

Mejores prácticas al usar enumeraciones

  1. Nombres significativos: Elige nombres claros para tus constantes de enumeración.
  2. Inmutabilidad: Mantén los campos de las enumeraciones como final.
  3. Encapsulamiento: Proporciona métodos de acceso en lugar de exponer campos directamente.
  4. Documentación: Documenta el propósito de la enumeración y el significado de cada constante.
  5. No abuses: Las enumeraciones son ideales para conjuntos fijos de valores relacionados; no las uses para modelar conceptos que pueden cambiar con frecuencia.

Resumen

Las enumeraciones en Java son una poderosa herramienta que va mucho más allá de simples listas de constantes. Nos permiten crear tipos de datos seguros con un conjunto fijo de valores posibles, añadiendo comportamiento y estado mediante constructores, campos y métodos. Son especialmente útiles para modelar conceptos del mundo real que tienen un número limitado de posibilidades, como estados, categorías o tipos predefinidos.

Al dominar las enumeraciones, podemos escribir código más legible, más seguro y más expresivo, reduciendo errores comunes como comparaciones incorrectas y mejorando la mantenbilidad de nuestras aplicaciones Java.