8

Urgh, I'm kind of confused on how enums work in Java. In C# and C++ (what I use normally), this seems okay, but Java wants to get mad at me >.>

   enum Direction
   {
      NORTH_WEST = 0x0C,
      NORTH      = 0x10,
      NORTH_EAST = 0x14,
      WEST       = 0x18,
      NONE       = 0x20,
      EAST       = 0x28,
      SOUTH_WEST = 0x24,
      SOUTH      = 0x30,
      SOUTH_EAST = 0x3C
   }

Could someone tell me what I'm doing wrong? Thanks

Here are the errors:

 ----jGRASP exec: javac -g Test.java

Test.java:79: ',', '}', or ';' expected
      NORTH_WEST = 0x0C,
                 ^
Test.java:79: '}' expected
      NORTH_WEST = 0x0C,
                  ^
Test.java:80: <identifier> expected
      NORTH      = 0x10,
           ^
Test.java:87: ';' expected
      SOUTH_EAST = 0x3C
                       ^
3
  • 5
    main problem is that the code you posted is not Java code. Commented Aug 26, 2010 at 0:36
  • 1
    This is completely off-topic, but why do you need Direction.NONE?! Commented May 7, 2014 at 15:37
  • See also the duplicate of this original Question: stackoverflow.com/q/3990319/642706 Commented Mar 8, 2018 at 17:41

4 Answers 4

28

For this scenario, it looks like you can simply use an instance field.

public enum Direction {
   NORTH(0x10), WEST(0x18), ...;

   private final int code;
   Direction(int code)  { this.code = code; }
   public int getCode() { return code; }
}

Java enum are implemented as objects. They can have fields and methods. You also have the option of declaring a constructor that takes some arguments, and providing values for those arguments in your constant declaration. You can use these values to initialize any declared fields.

See also


Appendix: EnumSet and EnumMap

Note that depending on what these values are, you may have an even better option than instance fields. That is, if you're trying to set up values for bit fields, you should just use an EnumSet instead.

It is common to see powers of two constants in, say, C++, to be used in conjunction with bitwise operations as a compact representation of a set.

// "before" implementation, with bitwise operations

public static final int BUTTON_A = 0x01;
public static final int BUTTON_B = 0x02;
public static final int BUTTON_X = 0x04;
public static final int BUTTON_Y = 0x08;

int buttonState = BUTTON_A | BUTTON_X; // A & X are pressed!

if ((buttonState & BUTTON_B) != 0) ...   // B is pressed...

With enum and EnumSet, this can look something like this:

// "after" implementation, with enum and EnumSet

enum Button { A, B, X, Y; }

Set<Button> buttonState = EnumSet.of(Button.A, Button.X); // A & X are pressed!

if (buttonState.contains(Button.B)) ... // B is pressed...

There is also EnumMap that you may want to use. It's a Map whose keys are enum constants.

So, where as before you may have something like this:

// "before", with int constants and array indexing

public static final int JANUARY = 0; ...

Employee[] employeeOfTheMonth = ...

employeeOfTheMonth[JANUARY] = jamesBond;

Now you can have:

// "after", with enum and EnumMap

enum Month { JANUARY, ... }

Map<Month, Employee> employeeOfTheMonth = ...

employeeOfTheMonth.put(Month.JANUARY, jamesBond);

In Java, enum is a very powerful abstraction which also works well with the Java Collections Framework.

See also

Related questions

Sign up to request clarification or add additional context in comments.

Comments

12

In Java enums don't hold any other values by default. You'll have to create a private field to store one. Try something like this

enum Direction {
   NORTH_WEST(0x0C),
   NORTH(0x10),
   ...

   private final int code;
   private Direction(int code) {
       this.code = code;
   }
}

Add getter if necessary.

Comments

2

if you have java 8 and are used to have your own toolbox. Then, here's kind of tool you can add:

  • Java 8 style interface

    public interface IntEnumInterface
    {
        // Will MAP all your application Enums (of type integer)
        final static Map<String, IntEnumInterfaceHelper> enumHelpers = new HashMap<String, IntEnumInterfaceHelper>();
        // Ensure Enum unique name accross your application
        default String getEnumUniqueName() { return this.getClass().getCanonicalName() + ":" + this.toString(); }
    
        default void init(int value)
        {
            IntEnumInterfaceHelper h = new IntEnumInterfaceHelper(){};
            h.init(value);
            enumHelpers.put(getEnumUniqueName(), h);
        }
    
        // Access the linked helper to retrieve integer value
        default public int getId() { return enumHelpers.get(getEnumUniqueName()).getValue(); }
    
        // helper (pseudo abstract)
        abstract class IntEnumInterfaceHelper
        {
            private int intValue;
            public void init(int value) { intValue = value; }
            public int getValue() { return intValue; }
        };
    }
    
  • From now on, you can define your enums this way:

    public enum RecordStatus implements IntEnumInterface
    {
        NEW(1), PROCESSING(2) ,PROCESS_COMPLETE(3), TO_DELETE(0);
        RecordStatus(int id) { init(id); }
    }
    
  • Then get the enum numeric values with:

    System.out.println(RecordStatus.NEW.getId());
    System.out.println(RecordStatus.PROCESSING.getId());
    System.out.println(RecordStatus.PROCESS_COMPLETE.getId());
    System.out.println(RecordStatus.TO_DELETE.getId());
    

1 Comment

Thanks, this is a great answer which saves a lot of boilerplate code!
1

Quick way when only consecutive numbers without particular values are needed:

enum PAGE {WATER, FIRE}
static final PAGE[] intToPage = PAGE.values();

usage

int i = PAGE.WATER.ordinal();
PAGE p = intToPage[i];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.