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 clone
méthode in Enum
garantit que les enum
constantes 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 enum
type n'existe au-delà de celles définies par les enum
constantes.
Puisqu'il n'y a qu'une seule instance de chaque enum
constante, il est permis d'utiliser l' ==
opérateur à la place de la equals
mé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 enum
constante . (La equals
méthode in Enum
est une final
méthode qui invoque simplement super.equals
son 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. enum
est 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 enum
sont:
- Ça marche.
- C'est plus rapide.
- C'est plus sûr à l'exécution.
- C'est plus sûr au moment de la compilation.