43 votes

Pourquoi Java n'autorise pas la surcharge de equals(Object) dans une Enum ?

J'ai remarqué que l'extrait suivant...

@Override
public boolean equals(Object otherObject) {
    ...
}

...n'est pas autorisé pour une Enum, puisque la méthode equals(Object x) est défini comme suit final en Enum . Pourquoi en est-il ainsi ?

Je n'arrive pas à penser à un cas d'utilisation qui nécessiterait de remplacer equals(Object) pour Enum. Je suis simplement curieux de connaître le raisonnement derrière ce comportement.

47voto

aioobe Points 158466

Tout sauf return this == other serait contre intuitive et violerait le principe du moindre étonnement . Deux constantes enum sont attendues equal s'il s'agit du même objet et seulement s'il s'agit du même objet. La possibilité de modifier ce comportement serait source d'erreurs.

Le même raisonnement s'applique à hashCode() , clone() , compareTo(Object) , name() , ordinal() y getDeclaringClass() .


Le JLS ne motive pas le choix de le rendre définitif, mais mentionne les égaux dans le contexte des enums aquí . Bribe :

La méthode equals dans Enum est une méthode finale qui invoque simplement super.equals sur son argument et renvoie le résultat, effectuant ainsi une comparaison d'identité.

3voto

Stephen C Points 255558

On dispose déjà d'une notion intuitive forte de ce que signifient les instances (valeurs) d'un système de gestion de l'information. enum pour être égaux. En autorisant la surcharge de la fonction equals conduirait à la violation de cette notion, ce qui entraînerait un comportement inattendu, des bogues, etc.

2voto

Parfois, nous devons traiter des données qui ne sont pas conformes aux normes de dénomination de Java. Il serait agréable de pouvoir faire quelque chose comme ceci :

public enum Channel
{
    CallCenter("Call Center"),
    BankInternal("Bank Internal"),
    Branch("Branch");

    private final String value;

    Channel(String value)
    {
        this.value = value;
    }

    @Override
    public String toString()
    {
        return value;
    }

    public static Channel valueOf(String value)
    {
        for (Channel c : Channel.values())
            if (c.value.equals(value))
                return c;
        return null;
    }

    @Override
    public boolean equals(Object other) 
    {
        if (other instanceof String)
            other = Channel.valueOf((String)other);
        return super.equals(other);
    }
}

La classe "String" devrait être modifiée pour s'adapter...

public boolean equals (Object object) {
    if (object == this) return true;
    if (object instanceof Enum) 
        object = object.toString();
    if (object instanceof String) {
        String s = (String)object;
        // There was a time hole between first read of s.hashCode and second read
        //  if another thread does hashcode computing for incoming string object
        if (count != s.count ||
            (hashCode != 0 && s.hashCode != 0 && hashCode != s.hashCode))
                return false;
        return regionMatches(0, s, 0, count);
    }
    return false;
}

1voto

Jean Hominal Points 7001

C'est précisément parce que les concepteurs de Java n'ont pu imaginer aucun cas d'utilisation concevable pour remplacer Enum.equals(Object) que cette méthode est déclarée comme finale - de sorte qu'un tel remplacement serait impossible.

0voto

Oak Points 10667

Je dois avouer que les enums sont la dernière chose que je voudrais surcharger. equals() dans.

Je pense que la raison equals() est final dans les enums est que Java encourage == pour la comparaison d'énumérations, et l'implémentation de equals() dans les enums l'utilise simplement, donc permettre equals() est d'éviter que == y equals() de se comporter différemment, ce à quoi les autres développeurs ne s'attendraient pas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X