Enum foi introduzido no Java 1.5 como um novo tipo cujos campos consistem em um conjunto fixo de constantes. Por exemplo, podemos criar direções como Enum Java com campos fixos como LESTE, OESTE, NORTE e SUL.
Enum Java
Neste tutorial, aprenderemos como criar um Enum. Também examinaremos os benefícios de usar enums em Java e as características dos tipos enum. Também aprenderemos a usar Java Enum
valueOf
, enum values
, EnumSet
e EnumMap
com exemplos.
Exemplo de Enum Java
A palavra-chave Java enum é usada para criar um tipo enum. Vamos dar uma olhada no programa de exemplo de enum Java.
package com.journaldev.enums;
public enum ThreadStates {
START,
RUNNING,
WAITING,
DEAD;
}
No exemplo acima, ThreadStates é o enum com campos de constantes fixas START, RUNNING, WAITING e DEAD.
Enum Java vs Constantes
Agora vejamos como o enum Java é melhor do que os campos de constantes normais em classes Java. Vamos criar uma classe de constantes similar em java.
package com.journaldev.enums;
public class ThreadStatesConstant {
public static final int START = 1;
public static final int WAITING = 2;
public static final int RUNNING = 3;
public static final int DEAD = 4;
}
Agora vamos ver como tanto enum quanto constantes são usados em um programa Java:
/**
* This method shows the benefit of using Enum over Constants
*/
private static void benefitsOfEnumOverConstants() {
//Os valores de enum são fixos
simpleEnumExample(ThreadStates.START);
simpleEnumExample(ThreadStates.WAITING);
simpleEnumExample(ThreadStates.RUNNING);
simpleEnumExample(ThreadStates.DEAD);
simpleEnumExample(null);
simpleConstantsExample(1);
simpleConstantsExample(2);
simpleConstantsExample(3);
simpleConstantsExample(4);
//podemos passar qualquer constante int
simpleConstantsExample(5);
}
private static void simpleEnumExample(ThreadStates th) {
if(th == ThreadStates.START) System.out.println("Thread started");
else if (th == ThreadStates.WAITING) System.out.println("Thread is waiting");
else if (th == ThreadStates.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
private static void simpleConstantsExample(int i) {
if(i == ThreadStatesConstant.START) System.out.println("Thread started");
else if (i == ThreadStatesConstant.WAITING) System.out.println("Thread is waiting");
else if (i == ThreadStatesConstant.RUNNING) System.out.println("Thread is running");
else System.out.println("Thread is dead");
}
Se olharmos o exemplo acima, temos dois riscos ao usar constantes que são resolvidos pelo enum.
- Podemos passar qualquer constante int para o método
simpleConstantsExample
mas podemos passar apenas valores fixos para simpleEnumExample, então ele fornece segurança de tipo. - Podemos alterar o valor das constantes int na classe
ThreadStatesConstant
mas o programa acima não lançará nenhuma exceção. Nosso programa pode não funcionar como esperado, mas se alterarmos as constantes de enum, receberemos um erro de tempo de compilação que remove qualquer possibilidade de problemas em tempo de execução.
Métodos de Enum Java
Agora vamos ver mais características do enum Java com um exemplo.
package com.journaldev.enums;
import java.io.Closeable;
import java.io.IOException;
/**
* This Enum example shows all the things we can do with Enum types
*
*/
public enum ThreadStatesEnum implements Closeable{
START(1){
@Override
public String toString(){
return "START implementation. Priority="+getPriority();
}
@Override
public String getDetail() {
return "START";
}
},
RUNNING(2){
@Override
public String getDetail() {
return "RUNNING";
}
},
WAITING(3){
@Override
public String getDetail() {
return "WAITING";
}
},
DEAD(4){
@Override
public String getDetail() {
return "DEAD";
}
};
private int priority;
public abstract String getDetail();
//Os construtores de enum devem sempre ser privados.
private ThreadStatesEnum(int i){
priority = i;
}
//Enum pode ter métodos
public int getPriority(){
return this.priority;
}
public void setPriority(int p){
this.priority = p;
}
//Enum pode sobrescrever funções
@Override
public String toString(){
return "Default ThreadStatesConstructors implementation. Priority="+getPriority();
}
@Override
public void close() throws IOException {
System.out.println("Close of Enum");
}
}
Pontos Importantes do Enum Java
Abaixo estão alguns dos pontos importantes para Enums em Java.
- Todos os enums em Java estendem implicitamente a classe
java.lang.Enum
, que por sua vez estende a classe Object e implementa as interfaces Serializable e Comparable. Portanto, não podemos estender nenhuma classe em um enum. - Como enum é uma palavra-chave, não podemos encerrar o nome do pacote com ela; por exemplo,
com.journaldev.enum
não é um nome de pacote válido. - Enums podem implementar interfaces. Como no exemplo de enum acima, ele está implementando a interface
Closeable
. - Os construtores de enums são sempre privados.
- Não podemos criar uma instância de enum usando o operador new.
- Podemos declarar métodos abstratos em enums Java; neste caso, todos os campos do enum devem implementar o método abstrato. No exemplo acima,
getDetail()
é o método abstrato, e todos os campos do enum o implementaram. - Podemos definir um método no enum, e os campos do enum também podem sobrescrevê-lo. Por exemplo, o método
toString()
é definido no enum, e o campo do enum START o sobrescreveu. - Os campos de enums em Java têm um namespace; podemos usá-los apenas com o nome da classe, como
ThreadStates.START
. - Enums podem ser usados em uma instrução switch; veremos isso em ação mais adiante neste tutorial.
- Podemos estender uma enumeração existente sem quebrar qualquer funcionalidade existente. Por exemplo, podemos adicionar um novo campo NOVO na enumeração ThreadStates sem impactar qualquer funcionalidade existente.
- Como os campos de enumeração são constantes, a melhor prática em Java é escrevê-los em letras maiúsculas e usar sublinhado para espaços. Por exemplo, EAST, WEST, EAST_DIRECTION, etc.
- As constantes de enumeração são implicitamente estáticas e finais
- As constantes de enumeração são finais, mas sua variável ainda pode ser alterada. Por exemplo, podemos usar o método
setPriority()
para alterar a prioridade das constantes de enumeração. Veremos isso em uso no exemplo abaixo. - Como as constantes de enumeração são finais, podemos compará-las com segurança usando os métodos “==” e equals(). Ambos terão o mesmo resultado.
Java EnumSet, EnumMap, valueOf()
Agora que conhecemos a maioria das características da Enumeração, vamos dar uma olhada em um programa de exemplo em Java. Em seguida, aprenderemos algumas outras características de uma enumeração.
package com.journaldev.enums;
import java.io.IOException;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;
public class JavaEnumExamples {
public static void main(String[] args) throws IOException {
usingEnumMethods();
usingEnumValueOf();
usingEnumValues();
usingEnumInSwitch(ThreadStatesEnum.START);
usingEnumInSwitch(ThreadStatesEnum.DEAD);
usingEnumMap();
usingEnumSet();
}
private static void usingEnumSet() {
EnumSet enumSet = EnumSet.allOf(ThreadStatesEnum.class);
for(ThreadStatesEnum tsenum : enumSet){
System.out.println("Using EnumSet, priority = "+tsenum.getPriority());
}
}
private static void usingEnumMap() {
EnumMap<ThreadStatesEnum, String> enumMap = new EnumMap<ThreadStatesEnum,String>(ThreadStatesEnum.class);
enumMap.put(ThreadStatesEnum.START, "Thread is started");
enumMap.put(ThreadStatesEnum.RUNNING, "Thread is running");
enumMap.put(ThreadStatesEnum.WAITING, "Thread is waiting");
enumMap.put(ThreadStatesEnum.DEAD, "Thread is dead");
Set keySet = enumMap.keySet();
for(ThreadStatesEnum key : keySet){
System.out.println("key="+key.toString()+":: value="+enumMap.get(key));
}
}
private static void usingEnumInSwitch(ThreadStatesEnum th) {
switch (th){
case START:
System.out.println("START thread");
break;
case WAITING:
System.out.println("WAITING thread");
break;
case RUNNING:
System.out.println("RUNNING thread");
break;
case DEAD:
System.out.println("DEAD thread");
}
}
private static void usingEnumValues() {
ThreadStatesEnum[] thArray = ThreadStatesEnum.values();
for(ThreadStatesEnum th : thArray){
System.out.println(th.toString() + "::priority="+th.getPriority());
}
}
private static void usingEnumValueOf() {
ThreadStatesEnum th = Enum.valueOf(ThreadStatesEnum.class, "START");
System.out.println("th priority="+th.getPriority());
}
private static void usingEnumMethods() throws IOException {
ThreadStatesEnum thc = ThreadStatesEnum.DEAD;
System.out.println("priority is:"+thc.getPriority());
thc = ThreadStatesEnum.DEAD;
System.out.println("Using overriden method."+thc.toString());
thc = ThreadStatesEnum.START;
System.out.println("Using overriden method."+thc.toString());
thc.setPriority(10);
System.out.println("Enum Constant variable changed priority value="+thc.getPriority());
thc.close();
}
}
Antes de explicar outros recursos importantes da enumeração, vamos ver a saída do programa acima.
priority is:4
Using overriden method.Default ThreadStatesConstructors implementation. Priority=4
Using overriden method.START implementation. Priority=1
Enum Constant variable changed priority value=10
Close of Enum
th priority=10
START implementation. Priority=10::priority=10
Default ThreadStatesConstructors implementation. Priority=2::priority=2
Default ThreadStatesConstructors implementation. Priority=3::priority=3
Default ThreadStatesConstructors implementation. Priority=4::priority=4
START thread
DEAD thread
key=START:: value=Thread is started
key=RUNNING:: value=Thread is running
key=WAITING:: value=Thread is waiting
key=DEAD:: value=Thread is dead
Using EnumSet, priority = 10
Using EnumSet, priority = 2
Using EnumSet, priority = 3
Using EnumSet, priority = 4
Pontos Importantes
- O método
usingEnumMethods()
mostra como criar um objeto enum e como podemos usar seus métodos. Também está mostrando o uso do métodosetPriority(int i)
para alterar a variável do enum. - O
usingEnumValueOf()
mostra o uso dejava.util.Enum
valueOf(enumType, name)
através do qual podemos criar um objeto enum a partir de uma String. Ele lançaIllegalArgumentException
se o tipo de enum especificado não tiver uma constante com o nome especificado, ou o objeto de classe especificado não representar um tipo enum. Ele também lançaNullPointerException
se algum dos argumentos for nulo. - O método
usingEnumValues()
mostra o uso do método values() que retorna uma matriz contendo todos os valores do enum na ordem em que são declarados. Note que este método é gerado automaticamente pelo compilador java para cada enum. Você não encontrará a implementação values() na classejava.util.Enum
. - O método
usingEnumInSwitch()
mostra como usar constantes enum em um switch case. - O método
usingEnumMap()
mostra o uso de java.util.EnumMap, que foi introduzido no Framework de Coleções do Java 1.5.EnumMap
é uma implementação de Map para uso com chaves de tipo enum. Todas as chaves em um enum map devem ser de um único tipo enum especificado, explicitamente ou implicitamente, quando o mapa é criado. Não podemos usar null como chave para EnumMap e EnumMap não é sincronizado. usingEnumSet()
método mostra o uso de java.util.EnumSet, que é uma implementação de Set para uso com tipos enum. Todos os elementos em um enum set devem vir de um único tipo enum que é especificado, explicitamente ou implicitamente, quando o conjunto é criado. EnumSet não é sincronizado e elementos nulos não são permitidos. Ele também fornece alguns métodos úteis comocopyOf(Collection<E> c)
,of(E primeiro, E... resto)
ecomplementOf(EnumSet<E> s)
.
Você pode verificar todos os exemplos em nosso Repositório do GitHub.
Referência: Documento da Oracle
Source:
https://www.digitalocean.com/community/tutorials/java-enum