2010-10-21 8 views
77

Attualmente sto creando costanti intere nel modo seguente.Memorizzazione di valori interi come costanti in modo Enum in java

public class Constants { 
public static int SIGN_CREATE=0; 
public static int SIGN_CREATE=1; 
public static int HOME_SCREEN=2; 
public static int REGISTER_SCREEN=3; 
} 

Quando provo a fare questo in modo enum

public enum PAGE{SIGN_CREATE,SIGN_CREATE,HOME_SCREEN,REGISTER_SCREEN} 

e Quando ho usato PAGE.SIGN_CREATE deve restituire 1;

+9

Non sarà la compilazione; hai definito "SIGN_CREATE" due volte. Inoltre, quelle non sono costanti - non sono "definitive". – BlairHippo

risposta

134

Beh, non riesco a farlo in quel modo. PAGE.SIGN_CREATE non restituirà mai 1; restituirà PAGE.SIGN_CREATE. Questo è il punto dei tipi enumerati.

Tuttavia, se siete disposti ad aggiungere un paio di tasti, è possibile aggiungere campi al enumerazioni, in questo modo:


    public enum PAGE{ 
     SIGN_CREATE(0), 
     SIGN_CREATE_BONUS(1), 
     HOME_SCREEN(2), 
     REGISTER_SCREEN(3); 

     private final int value; 

     PAGE(final int newValue) { 
      value = newValue; 
     } 

     public int getValue() { return value; } 
    } 

E poi chiamare PAGE.SIGN_CREATE.getValue() per ottenere 0.

+7

Questo in realtà non è vero. Puoi fare PAGE.SIGN_CREATE.ordinal(). Ciò restituirebbe 0. Probabilmente questa anwser è correlata a una versione java, che non aveva ancora questa caratteristica. – TheTrowser

+1

Che cosa vuoi combinare numeri e caratteri in un singolo enum? Per esempio. se voglio un enum per memorizzare 0, 1 e X? Grazie!! – russellhoff

+1

@BlairHippo: Posso fare qualcosa come 'PAGAGE pageEnum = PAGE (0)'. In parole semplici ho un valore con me e voglio ottenere l'enum corrispondente con il valore selezionato. Puoi rispondere? –

13

È possibile utilizzare ordinal. Quindi PAGE.SIGN_CREATE.ordinal() restituisce 1.

EDIT:

L'unico problema di questa operazione è che se si aggiungere, rimuovere o riordinare i valori enum si romperà il sistema. Per molti questo non è un problema in quanto non rimuoveranno enumerati e aggiungeranno solo valori aggiuntivi alla fine. Inoltre, non è peggio delle costanti intere che richiedono anche di non rinumerarle. Tuttavia è meglio usare un sistema come:

public enum PAGE{ 
    SIGN_CREATE0(0), SIGN_CREATE(1) ,HOME_SCREEN(2), REGISTER_SCREEN(3) 

    private int id; 

    PAGE(int id){ 
    this.id = id; 
    } 

    public int getID(){ 
    return id; 
    } 

} 

È quindi possibile utilizzare getID. Quindi PAGE.SIGN_CREATE.getID() restituisce 1.

+1

Pessima idea, poiché cambierà quando l'ordinamento delle costanti nella dichiarazione di classe cambia. –

+0

@ Michael - Questo è un buon punto. Ho aggiunto un ulteriore approccio per evitare questo problema. – Adam

2

È possibile memorizzare tale valore const nell'enumerazione in questo modo. Ma perché usare anche il const? Stai insistendo con l'enum?

public class SO3990319 { 
    public static enum PAGE { 
     SIGN_CREATE(1); 
     private final int constValue; 

     private PAGE(int constValue) { 
     this.constValue = constValue; 
     } 

     public int constValue() { 
     return constValue; 
     } 
    } 

    public static void main(String[] args) { 
     System.out.println("Name: " + PAGE.SIGN_CREATE.name()); 
     System.out.println("Ordinal: " + PAGE.SIGN_CREATE.ordinal()); 
     System.out.println("Const: " + PAGE.SIGN_CREATE.constValue()); 

     System.out.println("Enum: " + PAGE.valueOf("SIGN_CREATE")); 
    } 
} 

Edit:

Dipende da quello che si sta utilizzando i int di per se utilizzare o EnumMap campo di istanza.

+0

Sto affrontando il problema che non potevo passare il valore enum per cambiare caso! "caso Actions.CREATE.getAction()" dà un errore "le espressioni del caso devono essere espressioni costanti" –

+1

Actions.CREATE è l'enum. #getAction() non è ... – TJR

18

Il più Un motivo valido comune per volere una costante intera associata a ciascun valore enum è di interoperare con qualche altro componente che si aspetta ancora quegli interi (ad esempio un protocollo di serializzazione che non può essere modificato, o le enumerazioni rappresentano colonne in una tabella, ecc.).

In quasi tutti i casi, suggerisco di utilizzare un EnumMap invece. Disaccoppia i componenti in modo più completo, se questo è il problema, o se le enumerazioni rappresentano indici di colonne o qualcosa di simile, puoi facilmente apportare modifiche in seguito (o anche in fase di esecuzione se necessario).

private final EnumMap<Page, Integer> pageIndexes = new EnumMap<Page, Integer>(Page.class); 
pageIndexes.put(Page.SIGN_CREATE, 1); 
//etc., ... 

int createIndex = pageIndexes.get(Page.SIGN_CREATE); 

In genere è anche incredibilmente efficiente.

L'aggiunta di dati come questo all'istanza di enum può essere molto potente, ma è più frequente che non abusata.

Edit: appena realizzato Bloch ha affrontato questo in Effective Java/2 ° edizione, in Articolo 33: Uso EnumMap invece di indicizzazione ordinali.

+0

+1 sulla raccomandazione EnumMap. – I82Much

+1

Anche questo è abbastanza dettagliato. Significa che mantieni una struttura di dati completamente separata solo per avere una mappatura dalla chiave a un indice numerico derivato. Anche Bloch (Articolo 31) suggerisce valori di indice interi semplici per utilizzare il modello descritto nella risposta di @ BlairHippo a questa domanda. –

0

se si vuole essere in grado di convertire integer tornare a corrispondenti enum con valore selezionato vedere Constants.forValue(...) in seguito automaticamente generato il codice, ma se non è la risposta di BlairHippo è il modo migliore per farlo.

public enum Constants 
{ 
SIGN_CREATE(0), 
SIGN_CREATE(1), 
HOME_SCREEN(2), 
REGISTER_SCREEN(3); 

    public static final int SIZE = java.lang.Integer.SIZE; 

    private int intValue; 
    private static java.util.HashMap<Integer, Constants> mappings; 
    private static java.util.HashMap<Integer, Constants> getMappings() 
    { 
     if (mappings == null) 
     { 
      synchronized (Constants.class) 
      { 
       if (mappings == null) 
       { 
        mappings = new java.util.HashMap<Integer, Constants>(); 
       } 
      } 
     } 
     return mappings; 
    } 

    private Constants(int value) 
    { 
     intValue = value; 
     getMappings().put(value, this); 
    } 

    public int getValue() 
    { 
     return intValue; 
    } 

    public static Constants forValue(int value) 
    { 
     return getMappings().get(value); 
    } 
} 
0

ho trovato questo per essere utile:

http://dan.clarke.name/2011/07/enum-in-java-with-int-conversion/

public enum Difficulty 
{ 
    EASY(0), 
    MEDIUM(1), 
    HARD(2); 

    /** 
    * Value for this difficulty 
    */ 
    public final int Value; 

    private Difficulty(int value) 
    { 
     Value = value; 
    } 

    // Mapping difficulty to difficulty id 
    private static final Map<Integer, Difficulty> _map = new HashMap<Integer, Difficulty>(); 
    static 
    { 
     for (Difficulty difficulty : Difficulty.values()) 
      _map.put(difficulty.Value, difficulty); 
    } 

    /** 
    * Get difficulty from value 
    * @param value Value 
    * @return Difficulty 
    */ 
    public static Difficulty from(int value) 
    { 
     return _map.get(value); 
    } 
}