Primeiros passos com Java IX - Trabalhando com Enums
Published: 2022-02-21 10:52:57

---
title: Primeiros passos com Java IX - Trabalhando com Enums
published: true
date: 2021-11-30 00:00:01 UTC
tags: 
canonical_url: https://programadev.com.br/java-iniciante-p9/
---

Nos artigos anteriores estava sendo abordado o tema do básico de **Programação Orientada a Objetos** no **Java** ; porém existem outros tópicos da linguagem que seria bom serem apresentados. Iniciaremos com **Enumerações** e no final desse artigo você será capaz de entender o que são, como criá-las e usar.

**Enumerações** foram introduzidas no **Java5** e são uma forma dos desenvolvedores trabalharem melhor com dados que não podem ser alterados do que usando **constantes** , ela foi introduzida como sendo um tipo novo na linguagem o que significa que os desenvolvedores ganharam uma forma de checagem de tipos em tempo de compilação, o que ajuda muito no desenvolvimento principalmente por que possíveis erros são apontados no momento em que estamos escrevendo o código ao invés de só perceber, se perceber, o erro quando o código já está rodando e sendo usado. Juntamente com a tipagem foi adicionado um pacote novo, o **java.lang.Enum** e com isso uma série de métodos foram herdados quando uma **Enum** é criada.

Para entender a motivação para adicionar **Enums** no **Java** vamos supor que temos um código que valida o dia da semana, sabemos que os nomes dos dias da semana são imutáveis então podemos criar **constantes** para isso da seguinte forma:

```
public class DiaDaSemana {
    
    public static final String DOMINGO = "DOMINGO";
    public static final String SEGUNDA = "SEGUNDA";
    public static final String TERCA = "TERCA";
    public static final String QUARTA = "QUARTA";
    public static final String QUINTA = "QUINTA";
    public static final String SEXTA = "SEXTA";
    public static final String SABADO = "SABADO";
    
}
```

Tendo em mãos as **contantes** podemos criar o método que lida com o dia da semana e a partir dele toma alguma decisão:

```
public static void avaliaDiaDaSemana(String diaDaSemana){
    switch (diaDaSemana){
        case DiaDaSemana.DOMINGO:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DO DOMINGO");
            break;
        case DiaDaSemana.SEGUNDA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA SEGUNDA");
            break;
        case DiaDaSemana.TERCA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA TERCA");
            break;
        case DiaDaSemana.QUARTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA QUARTA");
            break;
        case DiaDaSemana.QUINTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA QUINTA");
            break;
        case DiaDaSemana.SEXTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA SEXTA");
            break;
        case DiaDaSemana.SABADO:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DO SABADO");
            break;
    }
}
```

No código acima foi feito uso de um **switch-case** sem uma cláusula **default** pois o desenvolvedor assumiu que como esse método sempre vai receber dias da semana não haveria o por que adicionar um **default** pois não seria executado. Agora vamos simular um caso de uso e testar essa hipótese:

```
public static void main(String[] args) {

    String diaDaSemana = "JANEIRO";
    
    avaliaDiaDaSemana(diaDaSemana);
}
```

Ao executar esse código nada será impresso pois houve uma falha no dado de entrada e isso não ficou explícito em nenhum ponto do código, uma possível solução aqui seria adicionar o **default** porém só estaríamos contornando o problema pois esse método permite a entrada de **Strings** mas no desenvolvimento nós queremos apenas dias da semana como uma entrada válida e se tentassem passar qualquer valor que não seja um dia da semana não poderia ser executado, graças as **Enums** isso se torna possível.

## Criando Enums[<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#Criando-Enums)

Criar uma **Enum** é como criar uma **classe** porém utilizamos a palavra reservada **enum** , para ficar claro o código abaixo é a criação de uma **Enum** representando os dias da semana:

```
public enum DiaDaSemana {
    DOMINGO,
    SEGUNDA,
    TERCA,
    QUARTA,
    QUINTA,
    SEXTA
}
```

Foi criado uma **Enum** simples e iremos evoluí-la ao passar do artigo e ver outras vantagens que ganhamos com iso. Uma **enum** carrega consigo um valor que por padrão é o próprio nome do item na **Enum** , então conseguimos fazer validações do tipo:

```
System.out.println(DiaDaSemana.valueOf("DOMINGO"));
```

O método **valueOf** que vem herdado do pacote **java.lang.Enum** retorna o item da **Enum** correspondente se o valor combinar com algum valor da **Enum** ou lança uma **exceção**  **IllegalArgumentException** caso não encontre nenhum valor que combine com a **String** informada, você pode ter notado que bastou adicionar a palavra **enum** e automaticamente ganhamos vários métodos como o **valueOf** , **name** , **ordinal** e etc.

## Usando Enums[<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#Usando-Enums)

Agora vamos alterar o método **avaliaDiaDaSemana** para trabalhar com a **Enum DiaDaSemana** :

```
public static void avaliaDiaDaSemana(DiaDaSemana diaDaSemana){
    switch (diaDaSemana){
        case DOMINGO:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DO DOMINGO");
            break;
        case SEGUNDA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA SEGUNDA");
            break;
        case TERCA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA TERCA");
            break;
        case QUARTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA QUARTA");
            break;
        case QUINTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA QUINTA");
            break;
        case SEXTA:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DA SEXTA");
            break;
        case SABADO:
            System.out.println("EXECUTANDO REGRA DE NEGÓCIO DO SABADO");
            break;
    }
}
```

Agora o método recebe a **Enum DiaDaSemana** e não há como passar outro valor que não seja um **DiaDaSemana** para o método **avaliaDiaDaSemana** :

```
avaliaDiaDaSemana(DiaDaSemana.DOMINGO);
```

Se tentarmos usar outro tipo que não seja um **DiaDaSemana** o código não irá compilar e se forçarmos o uso de outro valor será lançada uma **Exception** :

```
//Não compila
avaliaDiaDaSemana("OutroValor");
        
//IllegalArgumentException
avaliaDiaDaSemana(DiaDaSemana.valueOf("DIA QUE NÃO EXISTE"));
```

## Atributos e métodos com Enums[<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#Atributos-e-metodos-com-Enums)

Vimos o exemplo de como criar uma **Enum** do jeito mais simples possível, porém **Enums** podem ter atributos e métodos associados a elas. Isso ocorre pois uma **Enumeração** se comporta como se fosse uma classe estática, uma classe que não pode ser instanciada, então se é uma classe é possível existir atributos e métodos, a própria utilização de uma **Enum** se assemelha ao uso de um método estático, exemplo: **DiaDaSemana.DOMINGO**. Por conta disso caso seja necessário ter métodos ou atributos que auxiliem na execução de **Enums** podemos adicionar da seguinte maneira, começando pelo atributos:

```
public enum DiaDaSemana {
    DOMINGO("Domingo"),
    SEGUNDA("Segunda"),
    TERCA("Terça"),
    QUARTA("Quarta"),
    QUINTA("Quinta"),
    SEXTA("Sexta"),
    SABADO("Sábado");

    private String nome;

    DiaDaSemana(String nome){
        this.nome = nome;
    }
}
```

Como **Enums** se comportam como classes, com a exceção de que não podem ser instanciadas, podemos criar atributos mas para ligá-los ao itens da **Enum DiaDaSemana** é necessário que esses itens, da **Enum** , estejam instanciados dentro da **Enum** e para isso foi criado um construtor, que não é público, fazendo a ligação do atributo **nome** para cada item no **Enum** e por fim foi criado um valor para cada um deles.

Para criar métodos em **Enums** é o mesmo que criar métodos em classes:

```
public String getNome(){
    return this.nome;
}
```

A utilização dos métodos é muito parecido com o que vemos em métodos estáticos:

```
System.out.println(DiaDaSemana.DOMINGO.getNome());
```

E o resultado é o atributo nome que está associado ao item **DOMINGO** :

```
Domingo
```

Para esclarecer um pouco mais vamos criar outro método para verificar se o dia é final de semana:

```
public boolean verificaFinalDeSemana(){
    if(this == SABADO || this == DOMINGO){
        return true;
    }

    return false;
}
```

O método acima verifica se o dia testado é um sábado ou domingo e retorna um **true** caso seja e um **false** caso não seja, perceba que é passado o operador **this** e ele se refere a instancia do item do **Enum** que irá chamar o método **verificaFinalDeSemana** :

```
System.out.println(DiaDaSemana.SEGUNDA.verificaFinalDeSemana());
System.out.println(DiaDaSemana.SABADO.verificaFinalDeSemana());
```

Então quando o **Enum DiaDaSemana.SEGUNDA** chamar o método **verificaFinalDeSemana** o **this** se refere a **SEGUNDA** e assim em todos os itens da **Enum** , rodando esse código o resultado é:

```
false
true
```

## Conclusão[<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#Conclusao)

Quando se trabalha com **Enum** na maioria das vezes é por que existe uma coleção de dados que devem constante e queremos que isso seja garantido, **Enums** suprem muito bem essa necessidade. Existem outras maneiras de trabalhar com **Enums** como **EnumSet** e **EnumMap** porém esses são tópicos mais avançados de **Enums** e não tão comumente usados no dia-a-dia, porém com o que foi passado você será capaz de entender quando usar **Enums** e como usá-las para tirar o máximo proveito possivel delas.

O código deste artigo se encontra no [GitHub](https://github.com/guilhermegarcia86/helloworld)

Visite também o nosso canal no [Youtube](https://www.youtube.com/channel/UCDWmrzFPkkQf5VI_ziZrgvw) para mais acompanhar essa série de **Primeiros passos com o Java** e muito mais conteúdos sobre programação.