2010-10-21 6 views
77

Je crée actuellement des constantes entières de la manière suivante.Stockage de valeurs entières en tant que constantes en mode Enum dans 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; 
} 

Quand j'essaie de le faire de manière enum

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

et quand je PAGE.SIGN_CREATE il doit retourner 1;

+9

Ce ne compilera pas; vous avez défini "SIGN_CREATE" deux fois. En outre, ce ne sont pas des constantes - elles ne sont pas "définitives". – BlairHippo

Répondre

134

Eh bien, vous ne pouvez pas tout à fait le faire de cette façon. PAGE.SIGN_CREATE ne retournera jamais 1; il renverra PAGE.SIGN_CREATE. C'est le point des types énumérés.

Cependant, si vous êtes prêt à ajouter quelques touches, vous pouvez ajouter des champs à vos énumérations, comme ceci:


    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; } 
    } 

Et vous appelez PAGE.SIGN_CREATE.getValue() pour obtenir 0.

+7

Ce n'est pas vrai. Vous pouvez faire PAGE.SIGN_CREATE.ordinal(). Cela retournera 0. Probablement cette anwser est liée à une version de Java, qui n'a pas encore cette fonctionnalité. – TheTrowser

+1

Que voulez-vous mélanger les nombres et les caractères dans une seule énumération? Par exemple. si je veux une énumération pour stocker 0, 1 et X? Je vous remercie!! – russellhoff

+1

@BlairHippo: Puis-je faire quelque chose comme 'PAGE pageEnum = PAGE (0)'. En termes simples, j'ai une valeur avec moi et je veux obtenir l'énumération correspondante avec la valeur sélectionnée. Peux-tu répondre? –

13

Vous pouvez utiliser ordinal. Donc PAGE.SIGN_CREATE.ordinal() renvoie 1.

EDIT:

Le seul problème avec cela est que si vous ajoutez, supprimez ou réorganiser les valeurs enum vous briser le système. Pour beaucoup, ce n'est pas un problème car ils ne supprimeront pas les énumérations et ajouteront seulement des valeurs supplémentaires à la fin. Ce n'est pas non plus pire que les constantes entières qui vous obligent également à ne pas les renuméroter. Cependant, il est préférable d'utiliser un système comme:

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; 
    } 

} 

Vous pouvez ensuite utiliser getID. Donc PAGE.SIGN_CREATE.getID() renvoie 1.

+1

Mauvaise idée cependant, car elle changera quand l'ordre des constantes dans la déclaration de classe change. –

+0

@Michael - C'est un bon point. J'ai ajouté une approche supplémentaire pour éviter ce problème. – Adam

2

Vous pouvez stocker cette valeur const dans l'énumération comme cela. Mais pourquoi même utiliser le const? Avez-vous persisté 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:

Cela dépend de ce que vous utilisez les INT pour que ce soit d'utiliser le terrain EnumMap ou une instance.

+0

Je suis confronté au problème que je ne pouvais pas passer enum valeur pour changer de cas! "case Actions.CREATE.getAction()" il donne une erreur "les expressions de cas doivent être des expressions constantes" –

+1

Actions.CREATE est l'énumération. #getAction() n'est pas ... – TJR

18

Le plus Une raison valable commune pour vouloir une constante entière associée à chaque valeur enum est d'interopérer avec un autre composant qui attend toujours ces entiers (par exemple un protocole de sérialisation que vous ne pouvez pas changer, ou les énumérations représentent des colonnes dans une table, etc.).

Dans presque tous les cas, je suggère d'utiliser un EnumMap à la place. Il découble les composants plus complètement, si cela était le problème, ou si les énumérations représentent des index de colonnes ou quelque chose de similaire, vous pouvez facilement faire des changements plus tard (ou même au moment de l'exécution si besoin est).

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); 

C'est aussi incroyablement efficace, aussi.

L'ajout de données de ce type à l'instance enum elle-même peut être très puissant, mais il est le plus souvent abusé.

Edit: Bloch vient de réaliser cette adresse dans Effective Java/2ème édition, en Point 33: Utilisation EnumMap au lieu de l'indexation ordinale.

+0

+1 sur la recommandation EnumMap. – I82Much

+1

C'est aussi très bavard. Cela signifie que vous gardez une structure de données entièrement distincte juste pour avoir un mappage de la clé vers un index numérique dérivé. Bloch aussi (Item 31) suggère pour les valeurs d'index entières simples d'utiliser le modèle décrit dans la réponse de @ BlairHippo à cette question. –

0

si vous voulez être en mesure de convertir integer correspondant revenir à enum avec valeur sélectionnée voir ci-dessous Constants.forValue(...) dans le code généré automatiquement, mais sinon la réponse de BlairHippo est la meilleure façon de le faire.

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

Je trouve que cela est 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); 
    } 
} 
Questions connexes