views:

88

answers:

4

Hi, I'm currently creating integer constants in the following manner.

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

When i try to do this in enum manner

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

and When i used PAGE.SIGN_CREATE it should return 1;

+2  A: 

You can use ordinal. So PAGE.SIGN_CREATE.ordinal() returns 1.

EDIT:

The only problem with doing this is that if you add, remove or reorder the enum values you will break the system. For many this is not an issue as they will not remove enums and will only add additional values to the end. It is also no worse than integer constants which also require you not to renumber them. However it is best to use a system like:

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

}

You can then use getID. So PAGE.SIGN_CREATE.getID() returns 1.

Adam
Bad idea though, as it will change when the ordering of the constants in the class declaration changes.
Michael Borgwardt
@Michael - That's a good point. I added an additional approach to avoid that problem.
Adam
+2  A: 

You could store that const value in the enum like so. But why even use the const? Are you persisting the enum's?

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:

It depends on what you're using the int's for whether to use EnumMap or instance field.

TJ
+4  A: 

Well, you can't quite do it that way. PAGE.SIGN_CREATE will never return 1; it will return PAGE.SIGN_CREATE. That's the point of enumerated types.

However, if you're willing to add a few keystrokes, you can add fields to your enums, like this:


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

        private final int value;

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

        public int getValue() { return value; }
    }

And then you call PAGE.SIGN_CREATE.getValue() to get 0.

BlairHippo
+3  A: 

The most common valid reason for wanting an integer constant associated with each enum value is to interoperate with some other component which still expects those integers (e.g. a serialization protocol which you can't change, or the enums represent columns in a table, etc).

In almost all cases I suggest using an EnumMap instead. It decouples the components more completely, if that was the concern, or if the enums represent column indices or something similar, you can easily make changes later on (or even at runtime if need be).

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

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

It's typically incredibly efficient, too.

Adding data like this to the enum instance itself can be very powerful, but is more often than not abused.

Edit: Just realized Bloch addressed this in Effective Java / 2nd edition, in Item 33: Use EnumMap instead of ordinal indexing.

Mark Peters
+1 on the EnumMap recommendation.
I82Much