Classe Enum

Olá, Pessoal!!

Gostaria que alguém postasse um exemplo de código simples de uma classe Enum só pra eu ter uma idéia melhor pra que serve esse tipo de classe e como funciona.
Desde já agradeço. :smiley:

Exemplinho básico…

public enum Carro {
	ASTRA, VECTRA;
	private String nome;
	private float valor;

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public float getValor() {
		return valor;
	}

	public void setValor(float valor) {
		this.valor = valor;
	}

}
public class ExemploEnum {
	public static void main(String[] s) {
		Carro.ASTRA.setNome("Astra");
		Carro.ASTRA.setValor(50f);
		Carro.VECTRA.setNome("Vectra");
		Carro.VECTRA.setValor(60f);
		printCarro(Carro.ASTRA);
		printCarro(Carro.VECTRA);
	}

	public static void printCarro(Carro carro) {
		System.out.println("NOME:" + carro.getNome());
		System.out.println("VALOR:" + carro.getValor());
	}
}

Qualquer duvida… avise

O mais comum é não ter sets no enum, embora isso seja possível.

Também é possível adicionar métodos abstratos num enum.

Tem mais exemplos aqui:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

:)Ok, Valeu mesmo!!

A parte do funcionamento eu entendi muito bem, sem problemas.
Minha dúvida agora é com relação à utilidade.
Quais as vantagens de se ter uma classe desse tipo? :slight_smile:

É a melhor maneira de se representar uma quantidade fixa de valores.

Por exemplo, se você tiver uma classe teste, provavelmente o getResult poderia retornar apenas:
PASSED, FAILED e NOT_EXECUTED.

Use para isso um enum. Vocë garante que só esses resultados serão usados. O código fica claro (pois o nome fica explícito).

Para mais detalhes falando dos problemas dos enums com int e desse enum (conhecido como typesafe enum pattern) dê uma lida no item 21 do capítulo 5 do Effective Java:
http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf

Ali descreve por que foi criado e como o enum é implementado, além de comentar sobre vantagens desse método.

1 curtida

Eu tenho o seguinte caso:

Estou criando uma classe Cliente para um projeto da faculdade que inclui um Cadastro de Clientes. Dentre um dos atributos, há um que seria o sexo, a principio eu pensei em uma classe Enum que representasse os valores (masculino, feminino). Mas não tenho certeza se esta seria a melhor solução. Se for, como fazê-lo? :slight_smile:

Vc vai criar um Enum onde poderia gastar até um char[] usando M ou F?

Mas não DEVE ser usado SEMPRE que for necessário uma quantidade fixa de valores.Imagine um cadastro abarrotado de Enums para tudo:Conta Corrente,Sexo, Cor dos Olhos,Cor do Cabelo… :shock:

Eu discordo totalmente.

Por mim, sempre que uma quantidade fixa de valores for necessária, deve-se usar um enum.

Dá margem a menos erros, e torna-se impossível de um valor inválido ser inserido…

Esse conflito de opniões reflete exatamente minha dúvida.
Lógico que antes de ouvir falar nesse tipo de classe eu definia atributos normalmente seja da forma que foi mostrada acima com o char[] ou outras, enfim, sobrevivia :lol:. Mas de repente, tive a informação do Enum, trabalhando com valores fixos, e como sou do tipo que procura rever os próprios conceitos constantemente, decidi por bem investigar.
Mas pelo que estou vendo não há um consenso acerca da real utilidade.
Agora, a idéia de garantir que determinados valores serão utilizados e não “qualquer coisa tipo string” que entre no parâmetro de um set me parece bem interessante :!:

Do ponto de vista da validação, sim.
Mas dêem uma olhada no que o mau uso pode dar:
http://www.guj.com.br/posts/list/47085.java
Enum sofre compilação, então cuidado com os “dados fixos”.Dados fixos em um projeto podem não ser em outro.
Fora o custo tb(apesar de não ser muito).
Usar para usbtituir um array de char com “f” ou “m”, não vale a pena…

Clareza, e quando vc tem itens imutáveis, é punk. :wink:

E esse exemplo do vini, eu acho um dos melhores usos:

O custo do enum é baixíssimo.

Claro, não tão baixo quanto o uso de um tipo primitivo, mas se um dia um profiler acusar que o gargalo de performance está no seu enum e você corrigir substituindo por um tipo primitivo me avise, vou querer ver isso de perto… :lol:

O uso de memória também não é tão significativo assim, uma vez que o número de objetos instanciados é muito restrito.

Acho que o que o Ironlynx ressaltou é importante: Não dá para abusar dos enum também. A minha frase anterior soou nesse sentido então fica aqui meu mea culpa. Não conheço a fundo o sistema do post citado, mas a impressão que dá é que ele poderia substituir alguns enums por arquiteturas de classes, ou por outros tipos de padrões de projeto.

Não há sentido em usar enums também para valores que são cobertos por tipos primitivos, mesmo que haja apenas um pequeno range possível. Por exemplo, se você tiver um valor de um até quatro, não fará sentido o enum

enum Values {ONE, TWO, THREE, FOUR;}

É mais fácil usar o tipo primitivo e restringir os valores inválidos através de exceção. Até porque valores assim muitas vezes serão calculados e fica mais prático usar a própria variável como parâmetro de entrada num método, sem ter que converte-la para o enum anteriormente.

Também não faz sentido usar enums quando classes seriam mais adequadas. Pontos onde o número de constantes tentem a aumentar ou mudar muito com o tempo também são locais onde o uso dos enums pode ser questionado. Me cheira o caso do link que o IronLynx passou.

Ele definiu um enum “Postos” que seria melhor representado por uma classe e seus objetos, uma vez que novos postos poderão ser adicionados ou excluídos no futuro. Nesse caso, não se trata de um conjunto de constantes, mas mutável, que não deveria sequer estar “hard-coded”.

Finalmente, não têm sentido usar um enum para representar itens que podem ser obtidos dinamicamente. Enums são estáticos por default. Se você quer esse tipo de comportamento, herança e polimorfismo simples são mais recomendados. É o caso de drivers - que tem abstract factories onde o tipo concreto é obtido por reflexão, as factories conhecinhas não devem estar num enum.

O enum é muito prático para se representar valores fixos e, em alguns casos, objetos que implementam o pattern Strategy, quando existe uma quantidade limitada de estratégias disponíveis.

Um exemplo desse último caso é um enum que temos em nossos sistema para comparação de Strings. Ele tem os elementos:

public enum SearchCriteria {
   ENDS_WITH, STARTS_WITH, CONTAINS, REGEX;
};

Cada item desse enum implementa um método abstrato, boolean evaluate(String text);

A dica principal é. Não tenha medo de usar os enums. Use e abuse deles. Certamente você vai errar em diversas situações, e aprender com elas. Quando o uso parecer estranho ou questionável, posta aqui no GUJ! De repente, com mais gente vendo, surge uma sugestão melhor. :wink: