Pode ==
ser usado enum
?
Sim: as enumerações possuem controles de instância rígidos que permitem usar ==
para comparar instâncias. Aqui está a garantia fornecida pela especificação de idioma (ênfase minha):
Um tipo de enumeração não possui instâncias diferentes daquelas definidas por suas constantes de enumeração.
É um erro em tempo de compilação tentar instanciar explicitamente um tipo de enum. O final clone
método Enum
garante que as enum
constantes nunca possam ser clonadas, e o tratamento especial pelo mecanismo de serialização garante que instâncias duplicadas nunca sejam criadas como resultado da desserialização. A instanciação reflexiva dos tipos de enum é proibida. Juntos, essas quatro coisas garantem que não enum
existam instâncias de um tipo além daquelas definidas pelas enum
constantes.
Como há apenas uma instância de cada enum
constante, é permitido usar o ==
operador no lugar do equals
método ao comparar duas referências de objeto, se for sabido que pelo menos uma delas se refere a uma enum
constante . (O equals
método in Enum
é um final
método que apenas invoca super.equals
seu argumento e retorna o resultado, realizando uma comparação de identidade.)
Essa garantia é suficientemente forte que Josh Bloch recomenda que, se você insistir em usar o padrão singleton, a melhor maneira de implementá-lo é usar um elemento único enum
(consulte: Java Efetivo 2ª Edição, Item 3: Aplicar a propriedade singleton com um construtor privado ou um tipo de enum ; também Segurança de threads em Singleton )
Quais são as diferenças entre ==
e equals
?
Como um lembrete, é preciso dizer que, geralmente, ==
NÃO é uma alternativa viável equals
. Quando é, no entanto (como com enum
), há duas diferenças importantes a serem consideradas:
==
nunca joga NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
está sujeito à verificação de compatibilidade de tipo em tempo de compilação
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
Deve ==
ser usado quando aplicável?
Bloch menciona especificamente que classes imutáveis que têm controle adequado sobre suas instâncias podem garantir a seus clientes que ==
é utilizável. enum
é especificamente mencionado para exemplificar.
Item 1: Considere métodos estáticos de fábrica em vez de construtores
[...] permite que uma classe imutável garanta que não existem duas instâncias iguais: a.equals(b)
se e somente se a==b
. Se uma classe faz essa garantia, seus clientes podem usar o ==
operador em vez do equals(Object)
método, o que pode resultar em melhor desempenho. Os tipos enum fornecem essa garantia.
Para resumir, os argumentos para usar ==
on enum
são:
- Funciona.
- É mais rápido.
- É mais seguro em tempo de execução.
- É mais seguro em tempo de compilação.