Java Language Enums con constructores


Ejemplo

Una enum no puede tener un constructor público; sin embargo, los constructores privados son aceptables (los constructores para enums son de paquete privado por defecto):

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25); // usual names for US coins
    // note that the above parentheses and the constructor arguments match
    private int value;

    Coin(int value) { 
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Se recomienda mantener todos los campos privados y proporcionar métodos de obtención, ya que hay un número finito de instancias para una enumeración.


Si tuvieras que implementar un Enum como class , se vería así:

public class Coin<T extends Coin<T>> implements Comparable<T>, Serializable{
    public static final Coin PENNY = new Coin(1);
    public static final Coin NICKEL = new Coin(5);
    public static final Coin DIME = new Coin(10);
    public static final Coin QUARTER = new Coin(25);

    private int value;

    private Coin(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

int p = Coin.NICKEL.getValue(); // the int value will be 5

Las constantes de enumeración son técnicamente mutables, por lo que se podría agregar un setter para cambiar la estructura interna de una constante de enumeración. Sin embargo, esto se considera muy mala práctica y debe evitarse.

La mejor práctica es hacer que los campos de Enum sean inmutables, con final :

public enum Coin {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    private final int value;

    Coin(int value){ 
        this.value = value;
    }

    ...

}

Puede definir múltiples constructores en la misma enumeración. Cuando lo hace, los argumentos que pasa en su declaración de enumeración deciden a qué constructor se llama:

public enum Coin {
    PENNY(1, true), NICKEL(5, false), DIME(10), QUARTER(25);

    private final int value;
    private final boolean isCopperColored;

    Coin(int value){
        this(value, false);
    }

    Coin(int value, boolean isCopperColored){ 
        this.value = value;
        this.isCopperColored = isCopperColored;
    }

    ...

}

Nota: Todos los campos de enumeración no primitivos deberían implementar Serializable porque la clase Enum sí lo hace.