131 votes

Stockage des valeurs entières comme constantes dans la manière Enum en java

Je suis actuellement en train de créer des constantes entières de la manière suivante.

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

Lorsque j'essaie de le faire de manière enumérique

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

et quand j'ai utilisé PAGE.SIGN_CREATE il devrait retourner 1 ;

226voto

BlairHippo Points 2849

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

Cependant, si vous êtes prêt à ajouter quelques frappes, vous pouvez ajouter des champs à vos enums, 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 ensuite vous appelez PAGE.SIGN_CREATE.getValue() pour obtenir 0.

27voto

Mark Peters Points 42201

La raison la plus courante pour laquelle on souhaite avoir une constante entière associée à chaque valeur d'enum est l'interopérabilité avec un autre composant qui attend toujours ces entiers (par exemple, un protocole de sérialisation que vous ne pouvez pas changer, ou les enums représentent des colonnes dans une table, etc).

Dans presque tous les cas, je suggère d'utiliser un EnumMap à la place. Il découple plus complètement les composants, si c'est ce qui vous préoccupe, ou si les enums représentent des indices de colonne ou quelque chose de similaire, vous pouvez facilement apporter des modifications ultérieurement (ou même au moment de l'exécution si nécessaire).

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

En outre, il est généralement incroyablement efficace.

L'ajout de ce type de données à l'instance de l'énumération elle-même peut être très puissant, mais est le plus souvent utilisé de manière abusive.

Editar: Je viens de réaliser que Bloch a abordé cette question dans Effective Java / 2ème édition, dans Point 33 : Utilisation EnumMap au lieu de l'indexation ordinale .

20voto

Adam Points 14766

Vous pouvez utiliser [ordinal](http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Enum.html#ordinal()) . Donc PAGE.SIGN_CREATE.ordinal() renvoie à 1 .

EDITAR:

Le seul problème est que si vous ajoutez, supprimez ou réorganisez les valeurs de l'énumération, le système ne fonctionnera plus. Pour beaucoup, ce n'est pas un problème car ils ne supprimeront pas d'enum et ajouteront seulement des valeurs supplémentaires à la fin. Ce n'est pas plus grave que les constantes entières, qui ne doivent pas non plus être renumérotées. Cependant, il est préférable d'utiliser un système tel que :

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 alors utiliser getID . Donc PAGE.SIGN_CREATE.getID() renvoie à 1 .

7voto

Clayton Bell Points 180

J'ai trouvé cela 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);
    }
}

3voto

TJR Points 1034

Vous pourriez stocker cette valeur constante dans l'enum comme suit. Mais pourquoi utiliser le const ? Est-ce que vous persistez dans les 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"));
   }
}

Editar:

L'utilisation d'EnumMap ou d'un champ d'instance dépend de l'usage que vous faites des int.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X