|
mai 28
|
Um Enum (enumeração) é um tipo especial de classe. É basicamente uma lista de constantes enumeradas e está disponível a partir da versão 5 do Java. O Enum foi criado com o intuito de impedir que valores inesperados sejam recebidos em um trecho do seu código, impedindo com isso que erros sejam lançados em tempo de execução.
Imagine, por exemplo, que você tenha um Barco no rio Amazonas, no estado do Amapá, e que este viaje apenas pelos municípios deste estado. Você deverá ter na classe Barco um método que recebe como parâmetro a cidade para a qual o barco deve se deslocar. Como você faria? Bom, você poderia usar como parâmetro um objeto do tipo String, ou talvez um inteiro com o código da cidade. Seu código ficaria parecido com esse:
class Barco {
public void viajaPara(String cidade) {
System.out.println("Viajando para " + cidade);
}
}
O código funcionará perfeitamente, mas você correria o risco de um usuário informar uma cidade inesperada, veja:
public class Exemplo1 {
public static void main(String[] args) {
Barco barco = new Barco();
barco.viajaPara("Goiânia"); // ao executar, será mostrado na saída: Viajando para Goiânia
}
}
Sabemos que Goiânia está fora da rota normal do barco e que não deveria ser aceita como parâmetro, pois não é uma cidade do estado do Amapá. Como evitar este problema? Com certeza criar um monte de blocos condicionais com “if” para checar se trata-se de uma cidade do estado do Amapá não seria a melhor das soluções.
Pensando exatamente neste tipo de problema os desenvolvedores do Java criaram o Enum, nos possibilitando escolher um item dentre vários disponíveis em uma lista enumerada.
Veja agora o exemplo anterior utilizando um Enum:
enum CidadesNavegaveis {
AMAPA, CALCOENE, FERREIRA_GOMES, LARANJAL_DO_JARI, MACAPA, MAZAGAO, OIAPOQUE,
PORTO_GRANDE, SANTANA, SERRA_DO_NAVIO, TARTARUGALZINHO, VITORIA_DO_JARI;
}
class Barco {
public void viajaPara(CidadesNavegaveis cidade) { // perfeito! Impedimos um valor inesperado em tempo de execução!
System.out.println("Viajando para " + cidade);
}
}
public class Exemplo1 {
public static void main(String[] args) {
Barco barco = new Barco();
barco.viajaPara(CidadesNavegaveis.MACAPA); // recebendo um item dentre os disponíveis
}
}
Agora sim podemos assegurar de que nosso barco navegará apenas entre as cidades desejadas.
Um Enum pode ser declarado em um arquivo Java separado ou como um membro de uma classe, mas nunca dentro de um método.
Declarando um Enum em um arquivo Java separado
Arquivo CidadesNavegaveis.java:
enum CidadesNavegaveis {
AMAPA, CALCOENE, FERREIRA_GOMES, LARANJAL_DO_JARI, MACAPA, MAZAGAO, OIAPOQUE,
PORTO_GRANDE, SANTANA, SERRA_DO_NAVIO, TARTARUGALZINHO, VITORIA_DO_JARI;
}
Declarando um Enum como membro de uma classe
Arquivo Barco.java:
class Barco {
enum CidadesNavegaveis {
AMAPA, CALCOENE, FERREIRA_GOMES, LARANJAL_DO_JARI, MACAPA, MAZAGAO, OIAPOQUE,
PORTO_GRANDE, SANTANA, SERRA_DO_NAVIO, TARTARUGALZINHO, VITORIA_DO_JARI;
}
public void viajaPara(CidadesNavegaveis cidade) {
System.out.println("Viajando para " + cidade);
}
}
Cada item enumerado em um Enum é uma instância do próprio Enum. No exemplo acima, cada cidade enumerada (MACAPA, MAZAGAO, OIAPOQUE, etc) é uma instância do tipo CidadesNavegaveis. Confuso, não?!? Para que você entenda melhor, o Enum é algo parecido como isto:
class CidadesNavegaveis {
public static final CidadesNavegaveis AMAPA = new CidadesNavegaveis("AMAPA", 0);
public static final CidadesNavegaveis CALCOENE = new CidadesNavegaveis("CALCOENE", 1);
public static final CidadesNavegaveis FERREIRA_GOMES = new CidadesNavegaveis("FERREIRA_GOMES", 2);
public static final CidadesNavegaveis LARANJAL_DO_JARI = new CidadesNavegaveis("LARANJAL_DO_JARI", 3);
public static final CidadesNavegaveis MACAPA = new CidadesNavegaveis("MACAPA", 4);
// ...
public CidadesNavegaveis(String nome, int indice) {
// ...
}
}
Em um Enum todos os valores enumerados são static e final, portanto são constantes. Os valores são também implicitamente public, e cada valor guarda seu próprio índice, que é definido na ordem em que o item é declarado.
Além de definir constantes enumeradas, no Enum podemos também criar construtores, variáveis de instância, métodos e algo muito estranho chamado “corpo de classe específico da constante”.
Nosso barco agora sabe para quais cidades ele pode se deslocar, mas ainda não é inteligente o bastante para saber aonde fica cada cidade. Vamos ajudar no nosso barco relacionando cada cidade enumerada com sua respectiva coordenada geográfica. Podemos, para isto, utilizar um construtor para passar a coordenada como parâmetro e preencher uma variável de instância, caso precisemos recuperar este valor mais tarde. Nosso Enum ficaria assim:
enum CidadesNavegaveis {
AMAPA("2.051082,-50.794464"),
CALCOENE("1.933227,-50.736237"),
FERREIRA_GOMES("-0.116043,-51.28315"),
LARANJAL_DO_JARI("0.854155,-51.182556"),
MACAPA("0.034457,-51.066564"),
MAZAGAO("2.497911,-50.947037"),
OIAPOQUE("-0.906334,-51.965332");
CidadesNavegaveis(String coordenada) {
this.coordenada = coordenada;
}
private String coordenada;
public String getCoordenada() {
return coordenada;
}
}
Perceba que agora cada item enumerado passa como parâmetro uma String contendo a coordenada geográfica para o construtor do Enum, e essa String é armazenada em uma variável de instância. Essa variável poderá ser acessada posteriormente pelo método getCoordenada que criamos. Veja:
class Barco {
public void viajaPara(CidadesNavegaveis cidade) {
System.out.println("Viajando para " + cidade);
System.out.println("Coordenada: " + cidade.getCoordenada()); // Agora nossa classe Barco imprime também a coordenada geográfica da cidade enviada como parâmetro.
}
}
Não é possível invocar diretamente um construtor de um Enum, ele é acessado automaticamente pelo item enumerado, que enviará os parâmetros necessários, como fizemos no item enumerado MACAPA(“0.034457,-51.066564″) que passa uma String como parâmetro ao construtor. O Enum aceita construtores com mais de um parâmetro e também nos permite sobrecarregar o construtor.
Outro recurso importante em um Enum é a possibilidade de criar um “corpo de classe específico da constante”. Imagine que nosso barco precise saber qual cidade é a capital do estado. Ao invés de criar blocos condicionais com “if” podemos criar um método que retorne true caso a cidade seja capital e false caso não seja. Teremos então um método padrão que retornará sempre false, e para a cidade que é capital iremos sobrecarregar este método para que ele retorne true. Veja:
enum CidadesNavegaveis {
AMAPA("2.051082,-50.794464"),
CALCOENE("1.933227,-50.736237"),
FERREIRA_GOMES("-0.116043,-51.28315"),
LARANJAL_DO_JARI("0.854155,-51.182556"),
MACAPA("0.034457,-51.066564") { // corpo de classe específico da constante
public boolean isCapital() { // método sobrecarregado, para a capital
return true;
}
},
MAZAGAO("2.497911,-50.947037"),
OIAPOQUE("-0.906334,-51.965332");
CidadesNavegaveis(String coordenada) {
this.coordenada = coordenada;
}
private String coordenada;
public String getCoordenada() {
return coordenada;
}
public boolean isCapital() { // método padrão, para cidades não-capital
return false;
}
}
Agora nosso método viajaPara imprimirá true caso a cidade informada como parâmetro seja MACAPA, a capital do Amapá. Veja:
class Barco {
public void viajaPara(CidadesNavegaveis cidade) {
System.out.println("Viajando para " + cidade);
System.out.println("Coordenada: " + cidade.getCoordenada());
System.out.println("É capital: " + cidade.isCapital());
}
}
Não é possível estender explicitamente uma classe em um Enum. Ele estende implicitamente a classe java.lang.Enum, e herda desta alguns métodos, como o values() que retorna um Array contendo os itens enumerados definidos pelo programador. Este método nos permite, por exemplo, iterar entre nossos itens enumerados, veja:
public class Exemplo2 {
public static void main(String[] args) {
for (CidadesNavegaveis cidade: CidadesNavegaveis.values()) {
System.out.println(cidade);
}
}
}
O código acima imprimirá na tela todas as cidades enumeradas em nosso Enum CidadesNavegaveis.
Como vimos o Enum é um recurso bastante útil em Java, diminuindo o risco de um possível erro em tempo de execução.
cy-a
[Referências]
Mc Graw Hill / Alta Books
Sun Certified Java Associate Study Guide, 2010.
Certificação Sun Java Associado - SCJA: Guia de viagem para passar no exame, 2008.
Certificação Sun para Programador Java 6 Guia de Estudo, 2008.
Head First Java, 2005.
