Ao programar, muitas vezes encontramos a necessidade de limitar o conjunto de valores válidos para um determinado tipo de dados. Assim, por exemplo, o dia da semana pode ter 7 valores diferentes, o mês do ano pode ter 12 e a estação pode ter 4. Para resolver esses problemas, muitas linguagens de programação de tipo estaticamente fornecem um tipo de dados especial - enumeração ( Membros Enum são instâncias
Os elementos
enum
). A enumeração não apareceu em Java imediatamente. Uma construção de linguagem especializada enum
foi introduzida a partir da versão 1.5. Até este ponto, os programadores usaram outros métodos para implementar enumerações.
construção de enum
Vamos começar com um exemplo. Vamos descreverenum
o tipo de dados para armazenar a temporada usando:
enum Season { WINTER, SPRING, SUMMER, AUTUMN }
Bem, um exemplo simples de seu uso:
Season season = Season.SPRING;
if (season == Season.SPRING) season = Season.SUMMER;
System.out.println(season);
Como resultado, SUMMER será impresso no console . Acho que o exemplo é óbvio e não precisa de explicação.
Enum é uma classe
Ao declararenum
, criamos implicitamente uma classe derivada de java.lang.Enum
. Convencionalmente, a construção enum Season { ... }
é equivalente a class Season extends java.lang.Enum { ... }
. E embora o compilador não nos permita herdar explicitamente de java.lang.Enum
nós, ainda é fácil verificar se enum
ele foi herdado usando reflection
:
System.out.println(Season.class.getSuperclass());
O seguinte será exibido no console:
class java.lang.Enum
A herança real é executada automaticamente para nós pelo compilador Java. A seguir, vamos concordar em chamar a classe criada pelo compilador para implementar a enumeração de enum
-class e os valores possíveis do tipo enumerado como enum
elementos -a.
Membros Enum são instâncias enum
de uma classe que são estaticamente acessíveis
Os elementos enum Season (WINTER, SPRING и т.д.)
são instâncias estaticamente acessíveis enum
da -class Season
. Sua disponibilidade estática nos permite realizar comparações usando o operador de comparação de referência ==
. Exemplo:
Season season = Season.SUMMER;
if (season == Season.AUTUMN) season = Season.WINTER;
Nome e número de série do elemento enum
Conforme mencionado anteriormente, anyenum
-class herda java.lang.Enum
, que contém vários métodos úteis para todas as enumerações. Exemplo:
Season season = Season.WINTER;
System.out.println("season.name()=" + season.name() + " season.toString()=" + season.toString() + " season.ordinal()=" + season.ordinal());
A saída será:
season.name()=WINTER season.toString()=WINTER season.ordinal()=0
Os métodos name()
e toString()
são mostrados aqui ordinal()
. A semântica dos métodos é óbvia. Deve-se notar que esses métodos enum
são herdados da classe java.lang.Enum
. Obtendo um elemento enum
pela representação em string de seu nome Muitas vezes surge a tarefa de obter um elemento enum
por sua representação em string. Para isso, em cada enum
classe, o compilador cria automaticamente um método estático especial: public static EnumClass valueOf(String name)
, que retorna um elemento de enumeração EnumClass
com nome igual a name
. Exemplo de uso:
String name = "WINTER";
Season season = Season.valueOf(name);
Como resultado da execução do código, a variável season será igual a Season.WINTER
. Observe que se o elemento não for encontrado, uma IllegalArgumentException será lançada e, se for name
igual null
, uma NullPointerException será lançada . Aliás, isso é muitas vezes esquecido. Por alguma razão, muitos estão firmemente convencidos de que se uma função recebe um argumento e, sob certas condições, lança uma IllegalArgumentException , então, ao passá-la para lá , uma IllegalArgumentExceptionnull
certamente também será lançada . Mas isso não vem ao caso. Vamos continuar. Obtendo todos os elementos de uma enumeração Às vezes você precisa obter uma lista de todos os elementos de uma classe em tempo de execução. Para esses fins, o compilador cria um método em cada classe . Exemplo de uso: enum
enum
public static EnumClass[] values()
System.out.println(Arrays.toString(Season.values()));
Obtemos a saída:
[WINTER, SPRING, SUMMER, AUTUMN]
Observe que nem método valueOf()
nem método values()
são definidos na classe java.lang.Enum
. Em vez disso, eles são adicionados automaticamente pelo compilador quando enum
a classe é compilada. Adicionando seus próprios métodos à enum
classe Você tem a oportunidade de adicionar seus próprios métodos à enum
classe e aos seus elementos: O mesmo, mas com polimorfismo: O último exemplo demonstra o uso de herança em enum
. Mais sobre isso mais tarde. A herançaenum
em Java enum
permite implementar uma hierarquia de classes, cujos objetos são criados em uma única instância e são acessíveis estaticamente. Neste caso, os elementos enum
podem conter seus próprios construtores. Vamos dar um exemplo: Aqui declaramos uma enumeração Type
com três elementos INT
, INTEGER
e STRING
. O compilador criará as seguintes classes e objetos:
Type
- classe derivada dejava.lang.Enum
INT
— objeto da 1ª classe derivado deType
INTEGER
— objeto da 2ª classe derivado deType
STRING
— objeto da 3ª classe derivado deType
Object parse(String)
e um construtor Type(..., boolean)
. Ao mesmo tempo, objetos de classes INT
, INTEGER
existem STRING
em uma única cópia e são acessíveis estaticamente. Você pode verificar isso:
System.out.println(Type.class);
System.out.println(Type.INT.getClass() + " " + Type.INT.getClass().getSuperclass());
System.out.println(Type.INTEGER.getClass() + " " + Type.INTEGER.getClass().getSuperclass());
System.out.println(Type.STRING.getClass() + " " + Type.STRING.getClass().getSuperclass());
Obtemos a saída:
class Type
class Type$1 class Type
class Type$2 class Type
class Type$3 class Type
Pode-se observar que o compilador criou uma classe Type
e 3 nested
classes derivadas de Type
.
Classe enum descompilada com herança
Para confirmar o acima exposto, apresentamos também o resultado da descompilação da enumeraçãoType
do exemplo acima:
Enumerações e polimorfismo paramétrico
O leitor pode se perguntar: “ Por que a enumeração de Type acima não usa genéricos? ” O fato é que em Java é proibido o uso de genéricosenum
. Portanto, o exemplo a seguir não será compilado:
enum Type<T> {}
Um estudo mais aprofundado
Para uma compreensão mais profunda de como funcionam as enumerações em Java, recomendo que você se familiarize com o código fonte da classejava.lang.Enum
e também utilize o descompilador Jad para estudar o código gerado. Além disso, estudar o código-fonte da biblioteca Java é absolutamente necessário para entender quantos mecanismos em Java funcionam e é útil como referência para design orientado a objetos. Link para a fonte original: http://alexander.lds.lg.ua/
GO TO FULL VERSION