1. Histórico de como enumsurgiu

Hoje vamos explorar outro tipo de dado em Java: enum. O nome enumvem da palavra enumeração . O que é esse tipo de dados e para que serve?

Às vezes, um programador precisa criar um novo tipo de dado, cujos valores possíveis são limitados a uma pequena lista fixa.

Por exemplo, um DayOfTheWeektipo só pode receber os valores MONDAY, TUESDAY, WEDNESDAY, ... Existem 7 valores no total. Ou um Monthtipo só pode receber apenas os valores JANUARY, FEBRUARY, MARCH, ... São 12 valores no total.

Claro, você pode usar números (o inttipo): 1— Monday, 2— Tuesday, etc. Mas alguém pode acidentalmente atribuir valores inválidos como 8ou 0à sua variável.

Você poderia facilmente ter uma situação em que um programador pensa que os dias da semana (ou meses do ano) são numerados começando em zero, enquanto outros esperam que sua numeração comece em um, etc.

É por isso que Java introduziu enum, um tipo de dados que consiste em um conjunto finito de valores .


2. Declarando um tipo

A declaração de um novo enumtipo de dados se parece com isto:

enum TypeName
{
   VALUE1,
   VALUE2,
   VALUE3
}

Onde TypeNameestá o nome do novo tipo (classe), e os possíveis valores são separados por vírgulas e colocados entre chaves: Value1, Value2, Value3.

Como exemplo, vamos criar o nosso próprio DayOfTheWeek enum:

Código Observação
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY
}
Novo Daytipo

Segunda
Terça
Quarta
Quinta
Sexta
Sábado
Domingo

Aqui está como você atribui um valor a uma variável do nosso novo tipo:

Day day = Day.MONDAY;

Exemplo:

Código Observação
Day day = Day.FRIDAY;
System.out.println(day);
A saída da tela será:
FRIDAY


3. Métodos de umenum

Um enumtipo tem vários métodos embutidos, dois dos quais são muito interessantes:

O método estático values()retorna uma matriz de todos os valores do enumtipo:

Código Observação
Day[] days = Day.values();

for (Day day: days)
   System.out.println(day);







System.out.println(days[2]);
A daysvariável armazena um array contendo os valores do Daytipo (7 elementos)

Exiba o conteúdo do array na tela:
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

WEDNESDAY

O ordinal()método retorna o número ordinal da constante. Você o chama em um enumvalor em vez de uma enumclasse:

Código Saída do console
System.out.println(Day.MONDAY.ordinal());
System.out.println(Day.FRIDAY.ordinal());
System.out.println(Day.SUNDAY.ordinal());
0
4
6


4. Convertendo para uma classe

Na realidade, não há nada de mágico aqui. O compilador apenas nos deu um pouco de açúcar sintático. Em tempo de compilação, o Dayenum é convertido em uma classe comum:

Código, versão simplificada Observação
public class Day
{
   public static final Day MONDAY = new Day(0);
   public static final Day TUESDAY = new Day(1);
   public static final Day WEDNESDAY = new Day(2);
   public static final Day THURSDAY = new Day(3);
   public static final Day FRIDAY = new Day(4);
   public static final Day SATURDAY = new Day(5);
   public static final Day SUNDAY = new Day(6);

    private static final Day[] array = {MONDAY, TUESDAY,
      WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY};

   private final int value;

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

   public int ordinal()
   {
      return this.value;
   }

   public static Day[] values()
   {
      return array;
   }
}
Dayclass

Lista de constantes estáticas







Um array com todos os valores do Dayenum


Uma variável que armazena o valor de um Dayobjeto específico

A Dayclasse constructoré privada, o que significa que os objetos da Dayclasse só podem ser criados dentro da Dayclasse.



O ordinalmétodo deve ser chamado em um Dayobjeto.

Ele retorna o valor do objeto — o valuecampo.


O método retorna um array estático com todos os valores da Dayclasse

Se removermos todos os métodos e variáveis ​​estáticos da Dayclasse, obteremos o seguinte:

Código Observação
public class Day
{
  private int value;

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

  public int ordinal()
  {
    return this.value;
  }
}


A valuevariável armazena o valor do Dayobjeto

Dayobjetos só podem ser criados dentro da Dayclasse, desde que o construtor seja private.




O ordinal()método retorna o valor valuedo Dayobjeto.

Em outras palavras, nada assustador está acontecendo aqui. O compilador cria a Dayclasse, adiciona as constantes que representam os enumvalores, adiciona os métodos necessários e torna o construtor da classe private. Veremos como os construtores funcionam um pouco mais tarde.

Felizmente, agora está claro por que atribuímos um valor a uma variável dessa maneira:

Day day = Day.MONDAY;

MONDAYé apenas um campo estático (constante) na Dayclasse. Ao acessar métodos e campos estáticos de fora da classe, você deve indicar o nome da classe antes do nome do campo ou método.



5. Mais métodos de umenum

Cada enumclasse tem vários recursos interessantes.

Convertendo de e para uma string

Para converter um objeto enum em uma string, você precisa chamar seu toString()método.

String str = Day.MONDAY.toString();

Para converter na outra direção (de uma string para um Dayobjeto), você pode usar o valueOf()método estático:

Day day = Day.valueOf("MONDAY");

É super conveniente e será útil em muitos casos.

Convertendo para um número e vice-versa

Você já sabe como converter um enumobjeto em um número: chame o ordinal()método:

int index = Day.MONDAY.ordinal();

Para converter na outra direção (de um número para um Dayobjeto), você precisa de uma construção mais transparente:

Day day = Day.values()[2];

Exemplos:

Código Observação
Day day = Day.MONDAY;
int index = day.ordinal();
Day newDay = Day.values()[index+2];
Segunda-feira
Obtenha o índice de segunda-feira: 0
Dia da semana 2 dias após segunda-feira

Ponto importante: como enumos valores são um conjunto fixo de constantes, eles podem ser comparados usando == . Em outras palavras, você não pode ter dois MONDAYobjetos idênticos com endereços diferentes. Existe apenas uma única instância de cada valor de enumeração. E isso significa que comparar variáveis ​​enum usando == sempre funcionará.



6. Adicionando seus próprios métodos a umenum

Como an enumse torna uma classe comum em tempo de compilação, você pode declarar métodos nela. Esses métodos são simplesmente adicionados à classe que o compilador gera. Por exemplo, suponha que queremos Day enumretornar uma lista dos valores de enumeração em vez de uma matriz.

Então podemos adicionar o seguinte código:

Código Observação
enum Day
{
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY,
   SUNDAY;

   public static List<Day> asList()
   {
      ArrayList<Day> list = new ArrayList<Day>();

      Collections.addAll(list, values());

      return list;
   }

}








Um ponto e vírgula é necessário após a lista de valores.



Crie um ArrayListobjeto

Adicione os valores no array retornado pelo values()método.
Devolva a lista.

Agora este método pode ser chamado no código:

Código Observação
List<Day> list = Day.asList();
A listvariável armazenará uma lista de todos os valores do arquivo Day enum.