Why and when to use Enum in Java?

Asked

Viewed 27,667 times

42

Someone who is learning the language, novice or experienced, may never have crossed paths with Java enumerations. I have read several times that they are useful, for example, to implement the standards Singleton with more guarantees of visibility between threads.

What is the use of learning and using enum in day-to-day programming?

1 answer

47


As enum represent a fixed set of values in a more or less self-documented. Make code more explicit, more readable, and less vulnerable to programming errors.

A common alternative is to use String or int for constant values. The enum bring some advantages in relation to these types:

  • Compiler does not allow typographical errors, as can happen with string literals.

  • The compiler does not allow values that are outside the enumerated set, which is a consequence of the enumerations being guys themselves.

  • No need to write preconditions, or manual testing to ensure that the argument of a method is within the accepted range of values.

  • The type invariant is free, again because the enumerations are types, and define in the beginning the valid values.

  • Enumerations can define demeanor (methods) for their constants, as in any usual class.

  • The constants of an enumeration may specify their behavior: each constant may have its own definition of a method.

  • The virtual machine guarantees thread Safety when loading the enumeration.

  • Can also be used in switch.

There are still some creative uses of enumerations, such as state machines, as seen on this blog.


Let’s take a practical example of these advantages. Imagine a program that receives two colors and tries to combine them, according to the RGB system.

Using int

public static final int
    VERMELHO    = 1,
    AZUL        = 2,
    VERDE       = 4,
    AMARELO     = 5,
    CIANO       = 6,
    ROXO        = 3,
    BRANCO      = 7;

/**
 * @pre cor1 == VERMELHO || cor1 == AZUL || cor1 == VERDE ||
 *    cor1 == CIANO || cor1 == AMARELO || cor1 == ROXO || cor1 == BRANCO;
 * @pre cor2 == VERMELHO || cor2 == AZUL || cor2 == VERDE ||
 *    cor2 == CIANO || cor2 == AMARELO || cor2 == ROXO || cor2 == BRANCO;
 * @post cor1 == VERMELHO && cor2 == VERDE => return == AMARELO;
 * @post ...
 */
public static int combina(int cor1, int cor2) {
    if (!corValida(cor1)) return -1;
    if (!corValida(cor2)) return -1;
    return cor1 | cor2;
}

private boolean corValida(int cor) {
    return cor == VERMELHO || cor == VERDE || cor == AZUL ||
        cor == AMARELO || cor == CIANO || cor == ROXO || cor == BRANCO;
}

public static void main(String[] args) {
    int cor = combina(1, 2);
    // O que acontece quando VERMELHO e AZUL deixam de ser 1 ou 2?
    assert cor == ROXO;
}

Using enum

/*
 * Os codigos numéricos não fazem qualquer falta.
 * Seria possível resolver com switch, mas ficaria muito extenso para exemplo.
 * Contudo, um caso real deveria retirar os códigos,
 * para maiores garantias de que não há erro humano.
 */
public static enum Cor {
    VERMELHO(1), AZUL(2), VERDE(4), AMARELO(5), CIANO(6), ROXO(3), BRANCO(7);
    private final int codigo;

    Cor(int codigo) { this.codigo = codigo; }

    int codigo() { return codigo; }

    public static Cor porCodigo(int codigo) {
        for (Cor cor: Cor.values()) {
            if (codigo == cor.codigo()) return cor;
        }
        throw new IllegalArgumentException("codigo invalido");
    }
}

/**
 * @pre cor1 != null && cor2 != null;
 * @post cor1 == Cor.VERMELHO && cor2 == Cor.VERDE => return == Cor.AMARELO;
 * @post ...
 */
public static int combina(Cor cor1, Cor cor2) {
    int combinado = cor1.codigo() | cor2.codigo();
    return Cor.porCodigo(combinado);
}

public static void main(String[] args) {
    Cor cor = combina(Cor.VERMELHO, Cor.AZUL);
    assert cor == Cor.ROXO;
}
  • 5

    I really liked the answer! However, considering that she asks a question from the point of view of someone who is beginner in language, I think it would be interesting to add some examples of code. :)

  • 5

    @Luizvieira Thank you so much for the tip! I added an example using int and the same example with enum, to mark the difference between the two. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.