2012-10-22 8 views
8

Non so se sono l'unico a saperlo, ma i valori di un enum non sono implicitamente definitivi e possono essere modificati.Usi e possibilità di mutevolezza delle enumerazioni Java?

enum EnumTest { 
    TOTO("TOTO 1"), 
    TATA("TATA 2"), 
    ; 

    private String str; 

    private EnumTest(String str) { 
     this.str = str; 
    } 

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

    public static void main(String[] args) { 
    System.out.println(EnumTest.TATA); 
    EnumTest.TATA.str = "newVal"; 
    System.out.println(EnumTest.TATA); 
    } 

TATA 2 
newVal 

Questi valori sono oftenly inizializzati creazione dell'istanza (TOTO("TOTO 1")), ma, tranne me, non ho mai visto nessuno usando la parola finale per le variabili enum che dovrebbero essere immutabili. Non è questo il punto della domanda, mi chiedo solo se sono l'unica a saperlo.


Quello che mi piacerebbe sapere è se ci fosse qualche usecase per creare enfasi mutabili?

E mi piacerebbe anche conoscere i limiti di ciò che possiamo fare con le enumerazioni (buone pratiche o meno). Non l'ho provato, ma forse un enum può essere iniettato con i fagioli Spring? Almeno sembra che possiamo annotare ogni istanza (@Deprecated funziona bene per esempio), e anche i metodi.

+7

L'utilizzo di 'final' per i campi è una pratica comune nelle enumerazioni. –

risposta

7

Un possibile utilizzo potrebbe essere l'inizializzazione pigra (calcolare alcuni valori di campo quando vengono utilizzati per la prima volta, se spesso non vengono utilizzati affatto) o un oggetto singleton "normale" mutevole (come un registro o simile).

Nella maggior parte dei casi, tuttavia, gli oggetti enumerazione devono essere immutabili e i loro campi essere definitivi.

-3

Quello che mi piacerebbe sapere è se ci fosse qualche usecase per creare enfasi mutabili?

Le costanti di enumerazione non sono esse stesse modificabili, i loro campi sono mutevoli.

+1

Ecco cosa intende, come ho capito. –

+0

Sì, è quello che intendo, ma il caso "generale" è quello di creare enumerazioni immutabili, ma nessuno usa "finale" –

+0

Questo perché raramente c'è un 'enum' con un campo' public' o un metodo pubblico per cambiare un campo IMHO . Ma sono d'accordo che i campi dovrebbero essere dichiarati 'finali'. –

6

Mentre si indica un fatto interessante qui, per quanto mi riguarda, non esiste un caso per i campi enumerabili. Ci sono molte ragioni per cui l'uso di questa "funzione" linguistica ("bug"?) Sarebbe una cattiva idea, non ultimo il potenziale per confondere altri sviluppatori.

+3

Concordo sul fatto che le enumerazioni siano generalmente considerate immutabili e quindi la creazione di enumerazioni mutabili potrebbe portare a un uso improprio. Suggerirei che i valori mutabili associati alle enumerazioni sarebbero i migliori in un 'EnumMap'. Detto questo, penso che dire "no usecase" sia troppo forte. Gli enum in pratica rappresentano un'estensione del modello di singlton (un numero fisso di istanze) e con questo in mente potrebbero essere usati come qualsiasi altra classe. Ripeto ancora che gli sviluppatori MOST sono abituati a considerarli IMMUTABILI e quindi le enumerazioni mutabili potrebbero portare a problemi di manutenzione. –

+0

Grazie a dio dato che sono immutabili, in genere non c'è setter :) –

+0

@JohnB, se riesci a pensare ad un buon esempio di una situazione in cui l'uso di enum con campi mutabili è probabilmente migliore di qualsiasi altra alternativa, mi farebbe piacere vederlo come una risposta separata Ma la mia risposta è ancora: per quanto mi riguarda, c'è ** no ** usecase, almeno non un usecase che non potrebbe essere meglio servito con un ordinario 'class'. Hai ragione su quali enumerazioni sono "in pratica", ma concettualmente sono più vicine a un 'booleano' (che ha un insieme fisso di 2 valori possibili) o un' int' (set fisso di 2^32-1 valori possibili) . Riuscite ad immaginare di avere campi mutabili su 'true'? –

3

In risposta alla risposta e al commento di Alex D, sto prendendo il suo suggerimento di pubblicare un possibile caso d'uso. Prendiamo il vecchio esempio standard di enum di pianeti da cui si può calcolare la gravità, ecc. Immagina di voler mantenere il numero di colonie umane su ciascun pianeta. Sì, si potrebbe usare EnumMap, ma potrei vedere un caso in cui potrebbero essere necessari più campi mutabili e avere una mappa separata per ogni valore o una classe separata per contenere i valori mutabili associati a una enumerazione sarebbe contro-intuitiva.

Come ho affermato nei miei commenti, in generale credo che le enumerazioni siano e debbano essere immutabili, ma ritengo che affermare che non ci siano casi d'uso è troppo forte.

1

Non vedo alcun motivo per vietare l'uso di campi mutabili in enum s. Uno usa un enum per affermare che il valore del tipo appartiene a uno di un insieme finito (e noto) di possibilità. Non implica che quei valori non possano avere proprietà che si evolvono nel tempo.

Alcuni hanno chiesto casi d'uso per tale scenario. Un esempio potrebbe essere l'utilizzo di un tipo enum come ErrorCategory, che classificherà un errore in uno qualsiasi dei numeri predefiniti (ad esempio: DocumentationError, SemanticError, LayoutError ...).

Supponiamo che quelli ErrorCategories abbiano proprietà come requiresInstantIntervention o shouldFailBuild. Posso immaginare che il valore di tali proprietà potrebbe cambiare nel tempo o che possano essere configurabili dall'utente.

Mi rendo conto che ci sono (molti) altri modi per implementarlo (come ad esempio EnumMaps menzionato sopra) e si può sempre discutere sullo stile, ma per me un tale uso di enum s non è sbagliato di per sé. Poiché enum s sono tipi di riferimento in java, il comportamento di == rimane lo stesso di se non ci fossero proprietà mutabili in primo luogo.

0

Un'istanza di enum è un campo finale statico pubblico della classe enum. Quindi, se è mutabile, puoi modificarne lo stato in un altro thread. Questo potrebbe non essere quello che vuoi e potrebbe causare problemi se non te ne rendi conto.

Problemi correlati