enum.values ​​() - è un ordine di enumerazioni deterministiche restituite


105

Ho un'enumerazione SOME_ENUM:

public enum SOME_ENUM {
  EN_ONE,
  EN_TWO,
  EN_THREE;
}

Sarà SOME_ENUM.values()sempre tornare le enumerazioni nell'ordine delle dichiarazioni enum: EN_ONE, EN_TWO, EN_THREE? È una regola o non è garantito che non venga modificata nelle prossime versioni di JDK?


1
Eseguo l'iterazione sulla mia enumerazione per riempire un elenco, che rispetto ad altri punti del codice ho letto ripetendo su questa enumerazione.
Skarab

11
@ MitchWheat Per lo stesso motivo per cui faresti affidamento su un ordine di conservazione della lista: perché JDK è uno strumento che ti dà certe garanzie e fare affidamento su queste garanzie ti aiuta a scrivere codice più succinto e migliore. Certo, la domanda "È garantito che non venga cambiato?" è impossibile rispondere, di certo non ci si può fidare, niente ha quella garanzia.
Fletch

Risposte:


144

La specifica del linguaggio Java utilizza questo linguaggio esplicito:

@return un array contenente le costanti di questo tipo di enum, nell'ordine in cui sono dichiarate [Source]

Quindi, sì, verranno restituiti in ordine di dichiarazione. Vale la pena notare che l'ordine potrebbe cambiare nel tempo se qualcuno cambia la classe, quindi fai molta attenzione a come lo usi.


1
Se qualcuno aggiunge un valore nel mezzo in una versione successiva del codice, questo potrebbe irrigidirti, poiché cambierebbe il valore ordinale di altri elementi (vedi il metodo Enum.ordinal ()). Per questo motivo è meglio non fare affidamento sulla posizione ordinale come meccanismo di serializzazione (cioè, non memorizzarla nel db).
Matt

1
Collegamento alla fonte per quella specifica?
Dan Grahn


16

Sì, è garantito restituirli in quest'ordine.

Tuttavia, dovresti evitare di fare affidamento su questo e sul ordinal()valore, poiché può cambiare dopo aver inserito nuovi elementi, ad esempio.


+1 per il saggio consiglio. Sull'argomento di ordinal (), Effective Java suggerisce di aggiungere un campo membro al tipo enum.
ide

9

È determinato dall'ordine in cui sono dichiarati i valori. Tuttavia, non vi è alcuna garanzia che tu (o qualcun altro) non riordinerai / inserirai / rimuoverai i valori in futuro . Quindi non dovresti fare affidamento sull'ordine.

Efficace Java 2nd. L'edizione dedica il suo punto 31 a un argomento strettamente correlato: usa i campi istanza invece degli ordinali :

Non derivare mai un valore associato a un'enumerazione dal suo ordinale; memorizzalo invece in un campo istanza.


3
"nessuna garanzia che qualcuno non riordini i valori in futuro" - ma è proprio per questo che voglio fare affidamento sull'ordine :-)! Desidero poter riordinare gli articoli in futuro e quindi modificare il comportamento del mio programma. Bloch ha ragione nel non fare affidamento sull'ordinale e se l'esempio del richiedente coinvolge davvero enumerazioni come EN_TWO, allora si affida all'ordinale e non dovrebbe farlo. Ma fare affidamento sull'ordine va benissimo. Infatti, poiché l'ordine è garantito, creare un campo specifico per l'ordine significherebbe scrivere codice ridondante, il genere di cose che libri come Java efficace ti dicono di non fare.
Fletch

@Fletch, mi dispiace, non ti seguo abbastanza. A me sembra che tu stia cercando di usare enumper uno scopo per cui non era previsto.
Péter Török

diciamo che hai la famosa enumerazione "Planet". Nella tua interfaccia utente vuoi elencare i pianeti in ordine di distanza dal sole. Come puoi ottenerlo al meglio? Ordinerei le costanti del pianeta nell'ordine corretto all'interno della classe enum e quindi enumererei semplicemente l'enumerazione nell'interfaccia utente. Poiché l'ordine è affidabile, funzionerà. Questo è il genere di cose di cui sto parlando. Se un giorno la Terra si avvicina al sole più di Marte, ovviamente in un momento del genere la prima cosa nella tua mente calda sarà mantenere il tuo codice! Quindi vai alla tua classe Planet e sposta EARTH prima di MARTE.
Fletch

@Fletch, la Terra è già più vicina al Sole di Marte ;-) ma capisco cosa intendi. Tuttavia, in questo caso l'ordine dei pianeti è in realtà una funzione della loro distanza media dal Sole, che non è un semplice ordinale, quindi IMHO dovrebbe essere memorizzato come un campo distinto per ogni pianeta. Quindi puoi avere un banale comparatore che confronta i pianeti in base alla loro distanza media dal Sole e ordinarli usando questo comparatore. Questa è IMHO una soluzione pulita e infallibile. Considerando che la tua soluzione si interrompe non appena, ad esempio, un nuovo collega decide che i pianeti devono ovviamente essere elencati in ordine alfabetico ;-)
Péter Török

1
Hahaha ermm sì beh comunque è tutta una cospirazione, non c'è Marte. Inizialmente stavo per usare Saturno ma non riuscivo a ricordare a quali pianeti è vicino, ma il piano su Marte sembra essersi ritorto contro :-). Comunque ... in questo caso un comparatore andrebbe bene ma ha lo svantaggio di richiedere più codice, ovviamente. Penso che se ti affidi all'ordinamento del codice sorgente, documentarlo nei commenti della classe sarebbe una buona cosa. Il tuo collega potrebbe persino leggerlo.
Fletch

7

Le altre risposte sono buone, ma non commentare su questo:

"È una regola o non è garantito che non venga modificata nelle prossime versioni di Jdk?"

Non credo che esistano garanzie sui futuri JDK, quindi non dovresti nemmeno preoccuparti di loro. Non ci sarebbe modo di farli rispettare, i futuri lead di JDK potrebbero semplicemente decidere di rinnegare tali garanzie. È come il sistema parlamentare di Westminster: "Nessun Parlamento può vincolare un futuro parlamento".

Detto questo, la storia del JDK rivela un'eccellente coerenza. Non apportano molte modifiche sostanziali, quindi puoi essere abbastanza sicuro che il comportamento corrente specificato (non solo osservato) verrà preservato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.