IdleSun's Weblog

November 18, 2010

How to use an Java enum like an integer (for Android Message.what)

Filed under: Android,Java — idlesun @ 4:52 am

Java enum is powerful. However, it is tricky if you want to use it as integer just like in C/C++. Actually, it is not easy at all because Java enum elements are objects. So it is best to use Java enum as enum. But what about the case you need to pass it back an forth as an integer. One example is when you want to use enum for a ‘what’ of Android Message. Lets say you have defined the enum, WhatAbout, like this:

enum WhatAbout { ART, LIFE, MONEY, WORLD };

And you want to sendMessage to someHandler like this:

someHandler.sendMessage(updater.obtainMessage(WhatAbout.ART.ordinal(), 0, 0));

As you can see enum’s ordinal() method solves the issue. Now look at the receiver side. Here is the code for handleMessge() method of someHander

  public void handleMessage(Message msg) {
    if (msg.what == WhatAbout.ART.ordinal()) {
      // Do something about ART
    } else if (msg.what == WhatAbout.LIFE.ordinal()) {
      // Do something about LIFE
    } else ...
  }

It will work, but looks ugly. Using switch must be better. However, unfortunately, the ordinal() method cannot be a case expression because it is not a constant expression. So here is my trick to get around that restriction and use switch:

  static WhatAbout[] wa = WhatAbout.values();

  public void handleMessage(Message msg) {
    try {
      switch(wa[msg.what]) {
      case ART:
        // Do something about ART
        break;
      case LIFE:
        // Do something about LIFE
        break;
      ...
      }
    } catch (Exception x) {
      // Handle ArrayIndexOutOfBoundsException exception
    }
  }

The point is having an enum value array instantiated and use it in the switch expression.

Advertisements

5 Comments »

  1. Great tip, worked exactly as described when I refactored a bunch of ints into an enum. Thanks, idlesun.

    Comment by Artem Russakovskii — June 15, 2011 @ 1:21 am | Reply

  2. Yes, this is simple solution. But what about situation if you have local variable type ENUM and you want to send this variable as Message parameter:
    private enum STATE {STATE1, STATE2)
    private STATE m_state;

    public void SetState (STATE state) {
    m_state = state;
    m_Handler.obtainMessage (MESSAGE_STATE_CHANGED, ???state, -1).sendToTarget();
    }

    Comment by Vladimir — January 20, 2012 @ 6:36 am | Reply

  3. Solved by myself:
    m_Handler.obtainMessage (MESSAGE_STATE_CHANGE.ordinal(), state.ordinal() , -1).sendToTarget();

    Comment by Vladimir — January 20, 2012 @ 7:14 am | Reply

  4. Another approach – Will it work to do a WhatAbout.valueOf() to convert the int to the enum?

    Comment by Anil — September 10, 2014 @ 10:07 pm | Reply

    • The valueOf() method is to map from a string name to the corresponding enum constant. So I don’t think it will work.

      Comment by idlesun — September 18, 2014 @ 5:14 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: