Quali sono le enumerazioni e perché sono utili?

Oggi stavo sfogliando alcune domande su questo sito e ho trovato una menzione di un enum utilizzato in modalità singleton sui presunti vantaggi di sicurezza del thread per tale soluzione.

Non ho mai usato enum e sto programmando in Java da più di un paio d’anni. E a quanto pare hanno cambiato molto. Ora fanno anche il pieno sostegno dell’OOP dentro di loro.

Ora perché e perché dovrei usare enum nella programmazione quotidiana?

Dovresti sempre usare le enumerazioni quando una variabile (in particolare un parametro del metodo) può prendere solo una di una piccola serie di valori possibili. Gli esempi sarebbero cose come le costanti di tipo (stato del contratto: “permanente”, “temp”, “apprendista”) o flag (“esegui ora”, “rinvia l’esecuzione”).

Se si utilizzano enumerazioni anziché numeri interi (o codici stringa), si aumenta il controllo in fase di compilazione e si evitano errori nel passaggio di costanti non valide e si documentano quali valori sono legali da utilizzare.

A proposito, l’uso eccessivo di enumerazioni potrebbe significare che i tuoi metodi fanno troppo (spesso è meglio avere diversi metodi separati, piuttosto che un metodo che accetta diversi flag che modificano quello che fa), ma se devi usare flag o type codes, enum sono la strada da percorrere.

Ad esempio, quale è meglio?

 /** Counts number of foobangs. * @param type Type of foobangs to count. Can be 1=green foobangs, * 2=wrinkled foobangs, 3=sweet foobangs, 0=all types. * @return number of foobangs of type */ public int countFoobangs(int type) 

contro

 /** Types of foobangs. */ public enum FB_TYPE { GREEN, WRINKLED, SWEET, /** special type for all types combined */ ALL; } /** Counts number of foobangs. * @param type Type of foobangs to count * @return number of foobangs of type */ public int countFoobangs(FB_TYPE type) 

Una chiamata al metodo come:

 int sweetFoobangCount = countFoobangs(3); 

allora diventa:

 int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET); 

Nel secondo esempio, è immediatamente chiaro quali tipi sono consentiti, i documenti e l’implementazione non possono andare fuori sincrono e il compilatore può applicarlo. Inoltre, una chiamata non valida come

 int sweetFoobangCount = countFoobangs(99); 

non è più ansible

Perché utilizzare qualsiasi funzione di linguaggio di programmazione? Il motivo per cui abbiamo le lingue è per

  1. I programmatori possono utilizzare in modo efficiente e corretto gli algoritmi in un modulo.
  2. Manutentori per capire gli algoritmi che altri hanno scritto e apportano correttamente le modifiche.

Le enumerazioni migliorano sia la probabilità di correttezza che la leggibilità senza scrivere molto standard. Se sei disposto a scrivere boilerplate, allora puoi “simulare” enumerazioni:

 public class Color { private Color() {} // Prevent others from making colors. public static final Color RED = new Color(); public static final Color AMBER = new Color(); public static final Color GREEN = new Color(); } 

Ora puoi scrivere:

 Color trafficLightColor = Color.RED; 

Il boilerplate sopra ha lo stesso effetto di

 public enum Color { RED, AMBER, GREEN }; 

Entrambi forniscono lo stesso livello di controllo dell’aiuto dal compilatore. Boilerplate è solo più digitando. Ma il risparmio di molte digitazioni rende il programmatore più efficiente (vedi 1), quindi è una funzionalità utile.

Vale la pena anche per almeno un motivo in più:

Cambia istruzioni

Una cosa che la simulazione static final enum static final sopra non ti dà è un bel caso di switch . Per i tipi di enum, lo switch Java usa il tipo della sua variabile per dedurre l’ambito dei casi enum, quindi per l’ enum Color sopra è sufficiente dire:

 Color color = ... ; switch (color) { case RED: ... break; } 

Nota che non è Color.RED nei casi. Se non usi enum, l’unico modo per usare quantità nominate con switch è qualcosa come:

 public Class Color { public static final int RED = 0; public static final int AMBER = 1; public static final int GREEN = 2; } 

Ma ora una variabile per contenere un colore deve avere il tipo int . Il bel controllo del compilatore dell’enum e la simulazione static final sono finiti. Non felice.

Un compromesso consiste nell’utilizzare un membro con valori scalari nella simulazione:

 public class Color { public static final int RED_TAG = 1; public static final int AMBER_TAG = 2; public static final int GREEN_TAG = 3; public final int tag; private Color(int tag) { this.tag = tag; } public static final Color RED = new Color(RED_TAG); public static final Color AMBER = new Color(AMBER_TAG); public static final Color GREEN = new Color(GREEN_TAG); } 

Adesso:

 Color color = ... ; switch (color.tag) { case Color.RED_TAG: ... break; } 

Ma nota, ancora più lastra!

Usando un enum come un singleton

Dal testo qui sopra puoi vedere perché un enum fornisce un modo per implementare un singleton. Invece di scrivere:

 public class SingletonClass { public static final void INSTANCE = new SingletonClass(); private SingletonClass() {} // all the methods and instance data for the class here } 

e poi accedendo con

 SingletonClass.INSTANCE 

possiamo solo dire

 public enum SingletonClass { INSTANCE; // all the methods and instance data for the class here } 

che ci dà la stessa cosa Possiamo farla franca perché le enumerazioni Java sono implementate come classi complete con solo un po ‘di zucchero sintattico spruzzato sopra le righe. Questo è di nuovo meno stagnante, ma non è ovvio a meno che l’idioma non ti sia familiare. Inoltre non mi piace il fatto che tu abbia le varie funzioni enum anche se non hanno molto senso per il singleton: ord e values , ecc. (C’è in realtà una simulazione più complicata in cui Color extends Integer che funzionerà con switch, ma è così difficile che mostri ancora più chiaramente perché enum sia un’idea migliore).

Filo di sicurezza

La sicurezza del filo è un potenziale problema solo quando i singleton vengono creati pigramente senza alcun blocco.

 public class SingletonClass { private static SingletonClass INSTANCE; private SingletonClass() {} public SingletonClass getInstance() { if (INSTANCE == null) INSTANCE = new SingletonClass(); return INSTANCE; } // all the methods and instance data for the class here } 

Se molti thread chiamano getInstance contemporaneamente mentre INSTANCE è ancora nullo, è ansible creare un numero qualsiasi di istanze. Questo non va bene. L’unica soluzione è aggiungere l’accesso synchronized per proteggere la variabile INSTANCE .

Tuttavia, il codice static final sopra non ha questo problema. Crea l’istanza con entusiasmo in fase di caricamento della class. Il caricamento della class è sincronizzato.

L’ enum singleton è effettivamente pigro perché non è inizializzato fino al primo utilizzo. Anche l’inizializzazione di Java viene sincronizzata, quindi thread multipli non possono inizializzare più di un’istanza di INSTANCE . Stai ricevendo un singleton pigramente inizializzato con pochissimo codice. L’unico aspetto negativo è la syntax piuttosto oscura. È necessario conoscere l’idioma o comprendere a fondo come funzionano il caricamento e l’inizializzazione delle classi per sapere cosa sta succedendo.

Oltre ai già citati casi d’uso, trovo spesso enumerazioni utili per implementare il modello strategico, seguendo alcune linee guida OOP di base:

  1. Avere il codice in cui i dati sono (cioè, all’interno dell’enum stesso – o spesso all’interno delle costanti enum, che possono sovrascrivere i metodi).
  2. Implementazione di un’interfaccia (o più) per non associare il codice client all’enumerazione (che dovrebbe fornire solo una serie di implementazioni predefinite).

L’esempio più semplice sarebbe un insieme di implementazioni di Comparator :

 enum StringComparator implements Comparator { NATURAL { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }, REVERSE { @Override public int compare(String s1, String s2) { return -NATURAL.compare(s1, s2); } }, LENGTH { @Override public int compare(String s1, String s2) { return new Integer(s1.length()).compareTo(s2.length()); } }; } 

Questo “modello” può essere usato in scenari molto più complessi, facendo ampio uso di tutti i benefici che derivano dall’enumerazione: iterando sulle istanze, facendo affidamento sul loro ordine implicito, recuperando un’istanza con il suo nome, metodi statici che forniscono l’istanza giusta per contesti specifici, ecc. E tuttavia tutto questo è nascosto dietro l’interfaccia in modo che il codice funzioni con implementazioni personalizzate senza modifiche nel caso in cui si desideri qualcosa che non è disponibile tra le “opzioni predefinite”.

Ho visto questo applicato con successo per modellare il concetto di granularità del tempo (giornaliero, settimanale, ecc.) In cui tutta la logica era incapsulata in un enum (scegliendo la giusta granularità per un dato intervallo di tempo, comportamento specifico legato a ciascuna granularità come costante metodi ecc.). E ancora, la Granularity vista dal livello di servizio era semplicemente un’interfaccia.

Qualcosa che nessuna delle altre risposte ha coperto che rende le enumerazioni particolarmente potenti l’abilità di avere metodi di template . I metodi possono essere parte dell’enumerazione di base e sovrascritti da ciascun tipo. E, con il comportamento collegato all’enum, spesso elimina la necessità di costrutti if-else o di istruzioni switch come dimostra questo post del blog – dove enum.method() fa ciò che originariamente sarebbe eseguito all’interno del condizionale. Lo stesso esempio mostra anche l’uso di importazioni statiche con enumerazione e produce codice DSL molto più pulito.

Alcune altre qualità interessanti includono il fatto che le enumerazioni forniscono implementazione per equals() , toString() e hashCode() e implementano Serializable e Comparable .

Per una carrellata completa di tutto ciò che enum offre, consiglio vivamente la quarta edizione di Thinking in Java di Bruce Eckel che dedica un intero capitolo all’argomento. Particolarmente illuminanti sono gli esempi che coinvolgono un gioco Rock, Paper, Scissors (cioè RoShamBo) come enumerazione.

Dai documenti Java –

È necessario utilizzare i tipi enum ogni volta che è necessario rappresentare un insieme fisso di costanti. Ciò include tipi di enum naturali come i pianeti nel nostro sistema solare e insiemi di dati in cui si conoscono tutti i valori possibili al momento della compilazione, ad esempio le scelte in un menu, i flag della riga di comando e così via.

Un esempio comune è di sostituire una class con un insieme di costanti int finali statiche private (entro un numero ragionevole di costanti) con un tipo enum. Fondamentalmente se pensi di conoscere tutti i possibili valori di “qualcosa” al momento della compilazione, puoi rappresentarlo come un tipo di enumerazione. Le enum forniscono la leggibilità e la flessibilità su una class con costanti.

Pochi altri vantaggi che posso pensare ai tipi di enum. Costituiscono sempre un’istanza di una particolare class enum (da qui il concetto di usare le enumerazioni quando arriva il singleton). Un altro vantaggio è che puoi usare enumerazioni come un tipo di istruzione switch-case. Inoltre puoi usare toString () sull’enumerazione per stamparli come stringhe leggibili.

Ora perché e perché dovrei usare enum nella programmazione quotidiana?

È ansible utilizzare un Enum per rappresentare un insieme fisso fisso di costanti o una modalità di class interna aumentando la leggibilità. Inoltre, Enums può applicare una certa rigidità quando viene utilizzato nei parametri del metodo. Offrono l’interessante possibilità di passare informazioni a un costruttore come nell’esempio Planets sul sito di Oracle e, come hai scoperto, consentono anche un modo semplice per creare un modello singleton.

ex: Locale.setDefault(Locale.US) legge meglio di Locale.setDefault(1) e impone l’uso del set fisso di valori mostrato in un IDE quando si aggiunge il . separatore invece di tutti gli interi.

Enum s enumera un insieme fisso di valori, in modo auto-documentante.
Rendono il tuo codice più esplicito e anche meno sobject a errori.

Perché non usare String o int , invece di Enum , per le costanti?

  1. Il compilatore non consentirà errori di battitura , né valori fuori dal set fisso, poiché le enumerazioni sono di per sé tipi . conseguenze:
    • Non dovrai scrivere una pre-condizione (o un manuale if ) per assicurare che il tuo argomento sia nell’intervallo valido.
    • L’ invariante di tipo viene fornito gratuitamente.
  2. Le enumerazioni possono avere un comportamento, proprio come qualsiasi altra class.
  3. Probabilmente avrai bisogno di una quantità di memoria simile per usare String s, comunque (dipende dalla complessità Enum ).

Inoltre, ciascuna istanza di Enum è una class, per la quale è ansible definire il suo comportamento individuale.

Inoltre, assicurano la sicurezza del thread al momento della creazione delle istanze (quando viene caricato l’enum), che ha visto una grande applicazione nella semplificazione del Pattern Singleton .

Questo blog illustra alcune delle sue applicazioni, come una macchina di stato per un parser.

È utile sapere che le enums sono come le altre classi con campi Constant e un private constructor .

Per esempio,

 public enum Weekday { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } 

Il compilatore lo compila come segue;

 class Weekday extends Enum { public static final Weekday MONDAY = new Weekday( "MONDAY", 0 ); public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 ); public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 ); public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 ); public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 ); public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 ); public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 ); private Weekday( String s, int i ) { super( s, i ); } // other methods... } 

enum significa enumerazione cioè menzione (un certo numero di cose) una per una.

Un enum è un tipo di dati che contiene un insieme fisso di costanti.

O

Un enum è proprio come una class , con un insieme fisso di istanze note al momento della compilazione.

Per esempio:

 public class EnumExample { interface SeasonInt { String seasonDuration(); } private enum Season implements SeasonInt { // except the enum constants remaining code looks same as class // enum constants are implicitly public static final we have used all caps to specify them like Constants in Java WINTER(88, "DEC - FEB"), SPRING(92, "MAR - JUN"), SUMMER(91, "JUN - AUG"), FALL(90, "SEP - NOV"); private int days; private String months; Season(int days, String months) { // note: constructor is by default private this.days = days; this.months = months; } @Override public String seasonDuration() { return this+" -> "+this.days + "days, " + this.months+" months"; } } public static void main(String[] args) { System.out.println(Season.SPRING.seasonDuration()); for (Season season : Season.values()){ System.out.println(season.seasonDuration()); } } } 

Vantaggi dell’enum:

  • enum migliora la sicurezza del tipo durante il controllo in fase di compilazione per evitare errori in fase di esecuzione.
  • enum può essere facilmente utilizzato in switch
  • enum può essere attraversato
  • enum può avere campi, costruttori e metodi
  • enum può implementare molte interfacce ma non può estendere alcuna class perché estende internamente la class Enum

per di più

Oltre a tutto ciò che dicevano gli altri .. In un progetto più vecchio per cui lavoravo, un sacco di comunicazione tra quadro (applicazioni indipendenti) utilizzava interi che rappresentavano un piccolo insieme. È stato utile dichiarare il set come enum con metodi statici per ottenere l’object enum dal value e viceversa. Il codice sembrava più pulito, utilizzabile per il cambio di caso e una scrittura più semplice per i registri.

 enum ProtocolType { TCP_IP (1, "Transmission Control Protocol"), IP (2, "Internet Protocol"), UDP (3, "User Datagram Protocol"); public int code; public String name; private ProtocolType(int code, String name) { this.code = code; this.name = name; } public static ProtocolType fromInt(int code) { switch(code) { case 1: return TCP_IP; case 2: return IP; case 3: return UDP; } // we had some exception handling for this // as the contract for these was between 2 independent applications // liable to change between versions (mostly adding new stuff) // but keeping it simple here. return null; } } 

Crea object enum dai valori ricevuti (es. 1,2) usando ProtocolType.fromInt(2) Scrivi nei registri usando myEnumObj.name

Spero che questo ti aiuti.

Cos’è un enum

  • enum è una parola chiave definita per Enumerazione un nuovo tipo di dati. Le enumerazioni tipografiche dovrebbero essere utilizzate liberamente. In particolare, rappresentano una valida alternativa alle semplici costanti String o int utilizzate in API molto più vecchie per rappresentare insiemi di elementi correlati.

Perché usare enum

  • le enumerazioni sono sottoclassi finali implicite di java.lang.Enum
  • se un enum è un membro di una class, è implicitamente statico
  • il nuovo non può mai essere usato con un enum, anche all’interno del tipo enum stesso
  • nome e valoreFate semplicemente uso del testo delle costanti enum, mentre toString può essere sovrascritto per fornire qualsiasi contenuto, se desiderato
  • per le costanti enum, uguale e == ammonta alla stessa cosa, e può essere usato in modo intercambiabile
  • le costanti enum sono implicitamente statiche finali pubbliche

Nota

  • le enumerazioni non possono estendere nessuna class.
  • Un enum non può essere una superclass.
  • l’ordine di comparsa delle costanti enum è chiamato il loro “ordine naturale” e definisce l’ordine utilizzato anche da altri elementi: compareTo, ordine di valori di iterazione, EnumSet, EnumSet.range.
  • Un’enumerazione può avere costruttori, blocchi statici e di istanza, variabili e metodi ma non può avere metodi astratti.

Enum eredita tutti i metodi della class Object e della class astratta Enum . Quindi puoi usare i suoi metodi di riflessione, multithreading, serilization, confrontabile, ecc. Se dichiari una costante statica invece di Enum, non puoi. Oltre a ciò, il valore di Enum può essere passato anche al livello DAO.

Ecco un esempio di programma da dimostrare.

 public enum State { Start("1"), Wait("1"), Notify("2"), NotifyAll("3"), Run("4"), SystemInatilize("5"), VendorInatilize("6"), test, FrameworkInatilize("7"); public static State getState(String value) { return State.Wait; } private String value; State test; private State(String value) { this.value = value; } private State() { } public String getValue() { return value; } public void setCurrentState(State currentState) { test = currentState; } public boolean isNotify() { return this.equals(Notify); } } public class EnumTest { State test; public void setCurrentState(State currentState) { test = currentState; } public State getCurrentState() { return test; } public static void main(String[] args) { System.out.println(State.test); System.out.println(State.FrameworkInatilize); EnumTest test=new EnumTest(); test.setCurrentState(State.Notify); test. stateSwitch(); } public void stateSwitch() { switch (getCurrentState()) { case Notify: System.out.println("Notify"); System.out.println(test.isNotify()); break; default: break; } } } 

ENum sta per “Tipo enumerato”. È un tipo di dati con un insieme fisso di costanti che tu stesso definisci.

A mio parere, tutte le risposte che hai ottenuto sono valide, ma nella mia esperienza la esprimerei in poche parole:

Utilizzare le enumerazioni se si desidera che il compilatore verifichi la validità del valore di un identificatore.

Altrimenti, puoi usare le stringhe come hai sempre fatto (probabilmente hai definito alcune “convenzioni” per la tua applicazione) e sarai molto flessibile … ma non avrai il 100% di sicurezza contro gli errori di battitura sulle tue stringhe e le realizzerai solo in runtime.

Enum? Perché dovrebbe essere usato? Penso che sia più comprensibile quando lo userai. Ho la stessa esperienza

Supponiamo che tu abbia una operazione di creazione, cancellazione, modifica e lettura del database.

Ora se crei un enum come operazione:

 public enum operation { create("1") delete("2") edit("3") read("4") // You may have is methods here public boolean isCreate() { return this.equals(create); } // More methods like the above can be written } 

Ora puoi dichiarare qualcosa come:

 private operation currentOperation; // And assign the value for it currentOperation = operation.create 

Quindi puoi usarlo in molti modi. È sempre bene avere enum per cose specifiche, in quanto l’operazione di database nell’esempio precedente può essere controllata controllando currentOperation . Forse si può dire che questo può essere realizzato anche con variabili e valori interi. Ma credo che Enum sia un modo più sicuro e programmatore.

Un’altra cosa: penso che ogni programmatore ama il booleano , vero? Perché può memorizzare solo due valori, due valori specifici. Quindi, si può pensare che Enum abbia lo stesso tipo di strutture in cui un utente definirà quanti e quale tipo di valore memorizzerà, solo in un modo leggermente diverso. 🙂

Java ti permette di limitare la variabile ad avere solo uno dei pochi valori predefiniti – in altre parole, un valore da un elenco enumerato. Usare le enums può aiutare a ridurre i bug nel tuo codice. Ecco un esempio di enums al di fuori di una class:

 enums coffeesize{BIG , HUGE , OVERWHELMING }; //This semicolon is optional. 

Ciò limita il coffeesize ad avere: BIG , HUGE o OVERWHELMING come variabile.

Finora, non ho mai avuto bisogno di usare le enumerazioni. Ho letto su di loro da quando sono stati introdotti in versione 1.5 o versione tigre come è stato chiamato nel corso della giornata. Non hanno mai veramente risolto un “problema” per me. Per coloro che lo usano (e vedo che molti di loro lo fanno), sono sicuro che sicuramente serve a qualcosa . Solo il mio 2 quid.

Ci sono molte risposte qui, voglio solo indicarne due specifici:

1) Utilizzo di costanti Switch-case . Switch case non ti permetterà di usare oggetti String per caso. Le enumerazioni sono utili. Altro: http://www.javabeat.net/2009/02/how-to-use-enum-in-switch/

2) Implementare Singleton Design Pattern – Enum di nuovo, arriva in soccorso. Utilizzo, qui: Qual è l’approccio migliore per l’utilizzo di un Enum come un singleton in Java?

Ciò che mi ha dato il momento Ah-Ha è stata questa realizzazione: che Enum ha un costruttore privato accessibile solo tramite l’enumerazione pubblica:

 enum RGB { RED("Red"), GREEN("Green"), BLUE("Blue"); public static final String PREFIX = "color "; public String getRGBString() { return PREFIX + color; } String color; RGB(String color) { this.color = color; } } public class HelloWorld { public static void main(String[] args) { String c = RGB.RED.getRGBString(); System.out.print("Hello " + c); } } 

Per quanto mi riguarda, per rendere leggibile il codice in futuro, il caso di enumerazione più utile è rappresentato nel prossimo frammento:

 public enum Items { MESSAGES, CHATS, CITY_ONLINE, FRIENDS, PROFILE, SETTINGS, PEOPLE_SEARCH, CREATE_CHAT } @Override public boolean onCreateOptionsMenu(Menu menuPrm) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menuPrm); View itemChooserLcl; for (int i = 0; i < menuPrm.size(); i++) { MenuItem itemLcl = menuPrm.getItem(i); itemChooserLcl = itemLcl.getActionView(); if (itemChooserLcl != null) { //here Im marking each View' tag by enume values: itemChooserLcl.setTag(Items.values()[i]); itemChooserLcl.setOnClickListener(drawerMenuListener); } } return true; } private View.OnClickListener drawerMenuListener=new View.OnClickListener() { @Override public void onClick(View v) { Items tagLcl= (Items) v.getTag(); switch (tagLcl){ case MESSAGES: ; break; case CHATS : ; break; case CITY_ONLINE : ; break; case FRIENDS : ; break; case PROFILE: ; break; case SETTINGS: ; break; case PEOPLE_SEARCH: ; break; case CREATE_CHAT: ; break; } } }; 

Usa enum per TYPE SAFETY, questa è una funzione linguistica, quindi di solito ottieni:

  • Supporto per il compilatore (vedi immediatamente problemi di tipo)
  • Supporto degli strumenti in IDE (completamento automatico nel caso di commutazione …)

Le enumerazioni possono avere metodi, costruttori, puoi persino usare le enumerazioni all’interno delle enumerazioni e combinare enumerazioni con le interfacce.

Pensa alle enumerazioni come tipi per sostituire un insieme ben definito di costanti int (che Java “eredita” da C / C ++).

Il libro Effective Java 2nd Edition ha un intero capitolo su di loro e approfondisce i dettagli. Vedi anche questo post di Overflow dello stack .

Enum è la sostituzione della definizione tradizionale di più variabili finali statiche in Java, ed è molto usata quando si ha un insieme fisso di costanti ragionevole.

Vedo che il vantaggio più importante di enum è quando si definisce un metodo che accetta un argomento costante. In questo modo imponi ai chiamanti del metodo il commit delle costanti predefinite e impedisce loro di passare valori costanti casuali.

Riferimento: Come usare Enums in Java

Nella mia esperienza ho visto che l’uso di Enum a volte fa sì che i sistemi siano molto difficili da cambiare. Se si utilizza un Enum per un insieme di valori specifici del dominio che cambiano frequentemente e ha molte altre classi e componenti che dipendono da esso, si potrebbe voler considerare di non utilizzare un Enum.

Ad esempio, un sistema di trading che utilizza un Enum per mercati / scambi. Ci sono molti mercati là fuori ed è quasi certo che ci saranno molti sottosistemi che hanno bisogno di accedere a questo elenco di mercati. Ogni volta che vuoi aggiungere un nuovo mercato al tuo sistema, o se vuoi rimuovere un mercato, è ansible che tutto ciò che è sotto il sole debba essere ricostruito e rilasciato.

Un esempio migliore potrebbe essere qualcosa come un tipo di categoria di prodotto. Supponiamo che il tuo software gestisca l’inventario per un grande magazzino. Esistono molte categorie di prodotti e molte ragioni per cui questo elenco di categorie potrebbe cambiare. I manager possono voler immagazzinare una nuova linea di prodotti, sbarazzarsi di altre linee di prodotti e, eventualmente, riorganizzare le categorie di volta in volta. Se devi ribuild e ridistribuire tutti i tuoi sistemi semplicemente perché gli utenti vogliono aggiungere una categoria di prodotti, allora hai preso qualcosa che dovrebbe essere semplice e veloce (aggiungendo una categoria) e reso molto difficile e lento.

In conclusione, le enumerazioni sono buone se i dati che si rappresentano sono molto statici nel tempo e hanno un numero limitato di dipendenze. Ma se i dati cambiano molto e hanno molte dipendenze, allora c’è bisogno di qualcosa di dinamico che non venga controllato in fase di compilazione (come una tabella di database).

Userei enum come un utile strumento di mapping, evitando il multiplo if-else condizione che alcuni metodi siano implementati.

 public enum Mapping { ONE("1"), TWO("2"); private String label; private Mapping(String label){ this.label = label; } public static Mapping by(String label) { for(Mapping m: values() { if(m.label.equals(label)) return m; } return null; } } 

Quindi il metodo by(String label) consente di ottenere il valore enumerato non elencato. Inoltre, si può inventare la mapping tra 2 enumerazioni. Potrebbe anche provare “1 a molti” o “molti a molti” oltre alla relazione predefinita “uno a uno”

Alla fine, enum è una class Java. Quindi puoi avere il metodo main al suo interno, che potrebbe essere utile quando devi fare alcune operazioni di mapping su args subito.