Peut ==être utilisé sur enum?
Oui: les énumérations ont des contrôles d'instance serrés qui vous permettent d'utiliser ==pour comparer des instances. Voici la garantie fournie par la spécification de la langue (je souligne):
Un type enum n'a pas d'instances autres que celles définies par ses constantes enum.
Il s'agit d'une erreur au moment de la compilation de tenter d'instancier explicitement un type d'énumération. La final cloneméthode in Enumgarantit que les enumconstantes ne peuvent jamais être clonées, et le traitement spécial par le mécanisme de sérialisation garantit que les instances en double ne sont jamais créées à la suite de la désérialisation. L'instanciation réfléchie des types d'énumération est interdite. Ensemble, ces quatre éléments garantissent qu'aucune instance d'un enumtype n'existe au-delà de celles définies par les enumconstantes.
Puisqu'il n'y a qu'une seule instance de chaque enumconstante, il est permis d'utiliser l' ==opérateur à la place de la equalsméthode lors de la comparaison de deux références d'objet s'il est connu qu'au moins l'une d'entre elles se réfère à une enumconstante . (La equalsméthode in Enumest une finalméthode qui invoque simplement super.equalsson argument et renvoie le résultat, effectuant ainsi une comparaison d'identité.)
Cette garantie est suffisamment forte pour que Josh Bloch recommande que si vous insistez pour utiliser le modèle singleton, la meilleure façon de l'implémenter est d'utiliser un seul élément enum(voir: Effective Java 2nd Edition, Item 3: Enforce the singleton property with a constructeur privé ou type enum ; également Thread safety in Singleton )
Quelles sont les différences entre ==et equals?
Pour rappel, il faut dire qu'en général, ce ==n'est PAS une alternative viable à equals. Quand c'est le cas (comme avec enum), il y a deux différences importantes à considérer:
== ne jette jamais NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
== est soumis à une vérification de compatibilité des types lors de la compilation
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!
Doit ==être utilisé le cas échéant?
Bloch mentionne spécifiquement que les classes immuables qui ont un contrôle approprié sur leurs instances peuvent garantir à leurs clients qu'elles ==sont utilisables. enumest spécifiquement mentionné pour illustrer.
Point 1: envisager des méthodes d'usine statiques plutôt que des constructeurs
[...] il permet à une classe immuable de garantir qu'il n'existe pas deux instances égales: a.equals(b)si et seulement si a==b. Si une classe fait cette garantie, ses clients peuvent utiliser l' ==opérateur à la place de la equals(Object)méthode, ce qui peut améliorer les performances. Les types d'énumération offrent cette garantie.
Pour résumer, les arguments pour utiliser ==on enumsont:
- Ça marche.
- C'est plus rapide.
- C'est plus sûr à l'exécution.
- C'est plus sûr au moment de la compilation.