85

I'm having trouble declaring an enum. What I'm trying to create is an enum for a 'DownloadType', where there are 3 download types (AUDIO, VIDEO, AUDIO_AND_VIDEO).

I have implemented the code as follows:

private enum DownloadType {
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2);
    private final int value;

    private DownloadType(int value) {
        this.value = value;
    }
}

This works fine if I then use it like this:

DownloadType.AUDIO_AND_VIDEO.value;

However, I would like it so that I don't have to ask for the 'value'. I may be mistaken, but this is the way several classes work in Java such as Font, for example to set a font style, you use:

Font.PLAIN

Which returns an int value, we don't use:

Font.PLAIN.value
5
  • 1
    You may simply use DownloadType.AUDIO_AND_VIDEO also unless you need value, am I missing something? Commented Dec 9, 2012 at 21:37
  • @Nambari If I System.out.println(DownloadType.AUDIO_AND_VIDEO) it returns "AUDIO_AND_VIDEO" which is apparently of type 'DownloadType', not int. Commented Dec 9, 2012 at 21:38
  • 3
    I think you're confusing the purpose of enums. Why do you need the integer as well? Commented Dec 9, 2012 at 21:39
  • Because I was thinking if I want to then get the type I could use 'if (downloadType == DownloadType.AUDIO){}', is that not right? Commented Dec 9, 2012 at 21:40
  • 1
    It's the toString() method that gets invoked when you print your object. Also, PLAIN is a constant in Font class, not an enum. Commented Dec 9, 2012 at 21:40

8 Answers 8

111

Font.PLAIN is not an enum. It is just an int. If you need to take the value out of an enum, you can't avoid calling a method or using a .value, because enums are actually objects of its own type, not primitives.

If you truly only need an int, and you are already to accept that type-safety is lost the user may pass invalid values to your API, you may define those constants as int also:

public final class DownloadType {
    public static final int AUDIO = 0;
    public static final int VIDEO = 1;
    public static final int AUDIO_AND_VIDEO = 2;

    // If you have only static members and want to simulate a static
    // class in Java, then you can make the constructor private.
    private DownloadType() {}
}

By the way, the value field is actually redundant because there is also an .ordinal() method, so you could define the enum as:

enum DownloadType { AUDIO, VIDEO, AUDIO_AND_VIDEO }

and get the "value" using

DownloadType.AUDIO_AND_VIDEO.ordinal()

Edit: Corrected the code.. static class is not allowed in Java. See this SO answer with explanation and details on how to define static classes in Java.

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

6 Comments

Thanks for the clarification, this is making sense now. Instead of creating an enum, I'll make a public DownloadType { private static final int AUDIO = 0; } ... Should this be an InnerClass? Thanks for your answer.
@Cristian: It mainly depends on how you want to access it.
Thanks for your answers, was exactly what I was looking for - waiting 3 mins to accept
Did you mean public static final int AUDIO = 0;. As far as I know const isn't a valid Java keyword.
ordinal may lead to a less stable system
|
66

If you need to get the int value, just have a getter for the value in your ENUM:

private enum DownloadType {
    AUDIO(1), VIDEO(2), AUDIO_AND_VIDEO(3);
    private final int value;

    private DownloadType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

public static void main(String[] args) {
    System.out.println(DownloadType.AUDIO.getValue());           //returns 1
    System.out.println(DownloadType.VIDEO.getValue());           //returns 2
    System.out.println(DownloadType.AUDIO_AND_VIDEO.getValue()); //returns 3
}

Or you could simple use the ordinal() method, which would return the position of the enum constant in the enum.

private enum DownloadType {
    AUDIO(0), VIDEO(1), AUDIO_AND_VIDEO(2);
    //rest of the code
}

System.out.println(DownloadType.AUDIO.ordinal());            //returns 0
System.out.println(DownloadType.VIDEO.ordinal());            //returns 1
System.out.println(DownloadType.AUDIO_AND_VIDEO.ordinal()); //returns 2

6 Comments

Why do you need extra method when you can simply call .value and there is already a method ordinal() provided to get integer.
@Nambari umm, dint know enum has ordinal .. how stupid of me :P
@GanGnaMStYleOverFlowErroR Thanks for the answer, but I was actually looking to avoid calling .value, let alone creating another method and calling getValue() :)
@GanGnaMStYleOverFlowErroR: That is correct, I could have clarified that in my comment.
@Nambari no problomo, thanks for letting me know about ordinal() :)
|
18

First you should ask yourself the following question: Do you really need an int?

The purpose of enums is to have a collection of items (constants), that have a meaning in the code without relying on an external value (like an int). Enums in Java can be used as an argument on switch statments and they can safely be compared using "==" equality operator (among others).

Proposal 1 (no int needed) :

Often there is no need for an integer behind it, then simply use this:

private enum DownloadType{
    AUDIO, VIDEO, AUDIO_AND_VIDEO
}

Usage:

DownloadType downloadType = MyObj.getDownloadType();
if (downloadType == DownloadType.AUDIO) {
    //...
}
//or
switch (downloadType) {
  case AUDIO:  //...
          break;
  case VIDEO: //...
          break;
  case AUDIO_AND_VIDEO: //...
          break;
}

Proposal 2 (int needed) :

Nevertheless, sometimes it may be useful to convert an enum to an int (for instance if an external API expects int values). In this case I would advise to mark the methods as conversion methods using the toXxx()-Style. For printing override toString().

private enum DownloadType {
    AUDIO(2), VIDEO(5), AUDIO_AND_VIDEO(11);
    private final int code;

    private DownloadType(int code) {
        this.code = code;
    }

    public int toInt() {
        return code;
    }

    public String toString() {
        //only override toString, if the returned value has a meaning for the
        //human viewing this value 
        return String.valueOf(code);
    }
}

System.out.println(DownloadType.AUDIO.toInt());           //returns 2
System.out.println(DownloadType.AUDIO);                   //returns 2 via `toString/code`
System.out.println(DownloadType.AUDIO.ordinal());         //returns 0
System.out.println(DownloadType.AUDIO.name());            //returns AUDIO
System.out.println(DownloadType.VIDEO.toInt());           //returns 5
System.out.println(DownloadType.VIDEO.ordinal());         //returns 1
System.out.println(DownloadType.AUDIO_AND_VIDEO.toInt()); //returns 11

Summary

  • Don't use an Integer together with an enum if you don't have to.
  • Don't rely on using ordinal() for getting an integer of an enum, because this value may change, if you change the order (for example by inserting a value). If you are considering to use ordinal() it might be better to use proposal 1.
  • Normally don't use int constants instead of enums (like in the accepted answer), because you will loose type-safety.

1 Comment

+1 for pointing the toString() although the int becomes a String and I'm not going to use it because of that :)
10

Simply call the ordinal() method on an enum value, to retrieve its corresponding number. There's no need to declare an addition attribute with its value, each enumerated value gets its own number by default, assigned starting from zero, incrementing by one for each value in the same order they were declared.

You shouldn't depend on the int value of an enum, only on its actual value. Enums in Java are a different kind of monster and are not like enums in C, where you depend on their integer code.

Regarding the example you provided in the question, Font.PLAIN works because that's just an integer constant of the Font class. If you absolutely need a (possibly changing) numeric code, then an enum is not the right tool for the job, better stick to numeric constants.

3 Comments

I'm aware of ordinal(), but if I then want to change or specify a different order in future, this will cause problems. I'd like to specify the int value
@Cristian you shouldn't depend on the int value of an enum, only on its actual value. Enums in Java are not like enums in C, where you depend on their integer code.
@Cristian and regarding the example you provided in the question Font.PLAIN works because that's just an integer constant of the Font class. If you absolutely need a (possibly changing) numeric code, then an enum is not the right tool for the job, better stick to numeric constants.
5

You can try this code .

private enum DownloadType {
    AUDIO , VIDEO , AUDIO_AND_VIDEO ;

}

You can use this enumeration as like this : DownloadType.AUDIO.ordinal(). Hope this code snippet will help you .

Comments

3

If you are concatenating the enum with a string you can override toString method to return the int:

public String toString() {
    return value + "";
}

Then you could simply use:

String something = "foo" + DownloadType.AUDIO;

and the toString() method will be invoked.


Note that using toString() programmatically is generally considered poor practice - it is intended for human eyes only, however this is the only way to achieve what you're asking.

Comments

3

Do you want to this code?

public static enum FieldIndex {
    HDB_TRX_ID,     //TRX ID
    HDB_SYS_ID      //SYSTEM ID
}

public String print(ArrayList<String> itemName){
    return itemName.get(FieldIndex.HDB_TRX_ID.ordinal());
}

Comments

2

In my opinion the most readable version

public enum PIN_PULL_RESISTANCE {
    PULL_UP {
        @Override
        public int getValue() {
            return 1;
        }
    },
    PULL_DOWN {
        @Override
        public int getValue() {
            return 0;
        }
    };

    public abstract int getValue();
}

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.