Ho notato che il seguente frammento …
@Override public boolean equals(Object otherObject) { ... }
… non è consentito per un Enum, poiché il metodo equals(Object x)
è definito come final
in Enum
. Perché è così?
Non riesco a pensare a nessun caso d’uso che richiederebbe l’override degli equals(Object)
per Enum. Sono solo curioso di sapere il ragionamento dietro questo comportamento.
Qualunque cosa, tranne return this == other
sarebbe contro-intuitiva e violerebbe il principio del minimo stupore . Ci si aspetta che due costanti di enum siano equal
se e solo se sono lo stesso object e la possibilità di ignorare questo comportamento sarebbe soggetta a errori.
Lo stesso ragionamento si applica a hashCode()
, clone()
, compareTo(Object)
, name()
, getDeclaringClass()
e getDeclaringClass()
.
Mentre il JLS non motiva la scelta di renderlo definitivo, ma menziona uguali nel contesto delle enumerazioni qui . Frammento:
Il metodo equals in
Enum
è un metodo finale che richiama semplicementesuper.equals
sul suo argomento e restituisce il risultato, eseguendo così un confronto di id quadro.
C’è già una nozione forte e intuitiva di cosa significhi per le istanze (valori) di un enum
essere uguali. Consentire il sovraccarico del metodo equals
porterebbe a quella nozione violata, portando a comportamenti imprevisti, bug e così via.
È proprio perché i progettisti Java non potevano pensare a nessun caso d’uso concepibile per sovrascrivere Enum.equals (Object) che quel metodo è dichiarato come finale – in modo tale che tale override sarebbe imansible.
Devo confessare che le enumerazioni sono l’ultima cosa che vorrei sovrascrivere equals()
in.
Penso che la ragione equals()
sia definitiva nelle enumerazioni è che Java incoraggia ==
per il confronto enum, e l’implementazione di equals()
in enum semplicemente la usa, quindi permettere a equals()
di essere sovrascritto è prevenire ==
ed equals()
dal comportarsi diversamente, che è qualcosa che altri sviluppatori non si aspetterebbero.