Java Language Declarar y usar una enumeración básica


Ejemplo

Enum puede ser considerado como sintaxis de azúcar para una clase sellada que solo se crea una instancia de varias veces conocidas en tiempo de compilación para definir un conjunto de constantes.

Una enumeración simple para enumerar las diferentes temporadas se declararía de la siguiente manera:

public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

Si bien las constantes de enumeración no necesariamente tienen que estar en mayúsculas, es una convención de Java que los nombres de las constantes están en mayúsculas, con palabras separadas por guiones bajos.


Puedes declarar un Enum en su propio archivo:

/**
 * This enum is declared in the Season.java file.
*/
public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

Pero también puedes declararlo dentro de otra clase:

 public class Day {

    private Season season;

    public String getSeason() {
        return season.name();
    }

    public void setSeason(String season) {
        this.season = Season.valueOf(season);
    }

    /**
     * This enum is declared inside the Day.java file and 
     * cannot be accessed outside because it's declared as private.
     */
    private enum Season {
        WINTER,
        SPRING,
        SUMMER,
        FALL
    }

}

Finalmente, no puede declarar un Enum dentro de un cuerpo de método o constructor:

public class Day {

    /**
     * Constructor
    */
    public Day() {
        // Illegal. Compilation error
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }
    }

    public void aSimpleMethod() {
        // Legal. You can declare a primitive (or an Object) inside a method. Compile!
        int primitiveInt = 42;

        // Illegal. Compilation error.
        enum Season {
            WINTER,
            SPRING,
            SUMMER,
            FALL
        }

        Season season = Season.SPRING;
    }
    
}

No se permiten constantes de enumeración duplicadas:

public enum Season {
    WINTER,
    WINTER, //Compile Time Error : Duplicate Constants
    SPRING,
    SUMMER,
    FALL
} 

Cada constante de enumeración es public , static y final por defecto. Como todas las constantes son static , se puede acceder directamente usando el nombre de enumeración.

Las constantes de enumeración se pueden pasar como parámetros del método:

public static void display(Season s) {
    System.out.println(s.name());  // name() is a built-in method that gets the exact name of the enum constant
}

display(Season.WINTER);  // Prints out "WINTER"

Puede obtener una matriz de las constantes de enumeración utilizando el método values() . Se garantiza que los valores están en orden de declaración en la matriz devuelta:

Season[] seasons = Season.values();

Nota: este método asigna una nueva matriz de valores cada vez que se llama.


Para iterar sobre las constantes de enumeración:

public static void enumIterate() {
    for (Season s : Season.values()) {
        System.out.println(s.name());
    }
}

Puede utilizar enumeraciones en una instrucción de switch :

public static void enumSwitchExample(Season s) {
    switch(s) {
        case WINTER:
            System.out.println("It's pretty cold");
            break;
        case SPRING:
            System.out.println("It's warming up");
            break;
        case SUMMER:
            System.out.println("It's pretty hot");
            break;
        case FALL:
            System.out.println("It's cooling down");
            break;
    }
}

También puedes comparar constantes de enumeración usando == :

Season.FALL == Season.WINTER    // false
Season.SPRING == Season.SPRING  // true

Otra forma de comparar las constantes de enumeración es utilizando equals() como se muestra a continuación, lo que se considera una mala práctica, ya que puede caer fácilmente en las dificultades de la siguiente manera:

Season.FALL.equals(Season.FALL); // true
Season.FALL.equals(Season.WINTER); // false
Season.FALL.equals("FALL"); // false and no compiler error

Además, aunque el conjunto de instancias en la enum no se puede cambiar en tiempo de ejecución, las instancias en sí mismas no son inherentemente inmutables porque, como cualquier otra clase, una enum puede contener campos mutables como se muestra a continuación.

public enum MutableExample {
    A,
    B;

    private int count = 0;

    public void increment() {
        count++;
    }

    public void print() {
        System.out.println("The count of " + name() + " is " + count);
    }
}

// Usage:
MutableExample.A.print();       // Outputs 0
MutableExample.A.increment();
MutableExample.A.print();       // Outputs 1 -- we've changed a field   
MutableExample.B.print();       // Outputs 0 -- another instance remains unchanged

Sin embargo, una buena práctica es hacer que las instancias de enum inmutables, es decir, cuando no tienen campos adicionales o todos estos campos están marcados como final y son inmutables. Esto asegurará que durante toda la vida de la aplicación, una enum no perderá memoria y que es seguro usar sus instancias en todos los subprocesos.


Enums implícitamente implementa Serializable y Comparable porque la clase Enum hace:

public abstract class Enum<E extends Enum<E>>
extends Object
implements Comparable<E>, Serializable