292

I have a function which return a type int. However, I only have a value of the TAX enumeration.

How can I cast the TAX enumeration value to an int?

public enum TAX {
    NOTAX(0),SALESTAX(10),IMPORTEDTAX(5);

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

TAX var = TAX.NOTAX; // This value will differ

public int getTaxValue()
{
  // what do do here?
  // return (int)var;
}
1

8 Answers 8

392

You'd need to make the enum expose value somehow, e.g.

public enum Tax {
    NONE(0), SALES(10), IMPORT(5);

    private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

...

public int getTaxValue() {
    Tax tax = Tax.NONE; // Or whatever
    return tax.getValue();
}

(I've changed the names to be a bit more conventional and readable, btw.)

This is assuming you want the value assigned in the constructor. If that's not what you want, you'll need to give us more information.

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

4 Comments

I just tried it and realize it fails myEnumValue = MyEnum.valueOf(myInt); the arg has to be of type String - or is there something I am missing?
This solution is worse than nothing. Seems enums in Java just shouldn't be used? Or has JDK 1.8 changed that?
@ebyrob: Given the voting, it seems like many people disagree with you, as I do. If you want a fixed set of values, enums are absolutely fine.
@ebyrob before saying anything about the solution, you should've taken a look at who answered it - SO God Jon Skeet himself!!
285

I prefer this:

public enum Color {

   White,

   Green,

   Blue,

   Purple,

   Orange,

   Red
}

then:

//cast enum to int
int color = Color.Blue.ordinal();

12 Comments

This is incorrect/not recommended by Joshua Bloch in his book Effective Java (2nd ed). See item 31.
@user504342 I do not have the 2nd edition of the book so can you please give us the gist of why it is not recommended?
2 reasons: one, any association between the ordinal values and the constants will break if new constants are added, and two the API docs specifically recommend against it.
So clean and perfect. I see a few "don't do it" and "not recommended". I'll have to research on why it's considered bad. Some of the bloated samples look bad IMO. So much work to do such a simple task.
I love how the javadoc for ordinal() says "most programmers will have no use for this method". Actually having a list of unique integers without having to assign them myself is often the main reason I use enums. They do not 'break' when new constants are added, provided you add them at the end. If you're using them in communications with outside programs and don't add the new value in the outside program then it's broken anyway. Been doing this for 20 years in C and never had any issues. Also, giving "it's not recommended" as the answer to "why is it not recommended" is not a reason :)
|
28

Sometime some C# approach makes the life easier in Java world..:

class XLINK {
static final short PAYLOAD = 102, ACK = 103, PAYLOAD_AND_ACK = 104;
}
//Now is trivial to use it like a C# enum:
int rcv = XLINK.ACK;

3 Comments

For me this is the most desirable way to go. I get the benefits of enum (code clarity), a data type that is DB friendly, and I don't have to research 100 enum alternatives to do it the "android way". Simple and effective.
Nice. It's as if the java enum is just completely disconnected from the reality of what an enum is used for... especially if people then start abusing it for things like singletons. This approach does have the disadvantage it doesn't have an easy way to get all values though.
Doesn't this have the disadvantage of trying to pass an enum value to a method? You can no longer pass a XLINK to a method, because it doesn't represent anything concrete. You lose the typing into your method. The method signature would have to read short instead of XLINK.
18

If you want the value you are assigning in the constructor, you need to add a method in the enum definition to return that value.

If you want a unique number that represent the enum value, you can use ordinal().

5 Comments

Be careful. There are many more developmental anti-patterns that rely on ordinal() than valid use cases for ordinal(). If you need to store a unique value for the enum, then just store the enum. There are EnumSets, Lists of Enums, EnumMaps, and nearly any other Enum collection you might want available.
@EdwinBuck: That is good to point out, I just wanted to mention the existence of ordinal() because the OP didn't make it clear what he wanted the int to actually be.
Don't get ordinal. Please check the enum api regarding this. Up-vote removed.
I wonder what peoples' thoughts are about the use of ordinal() internally within the enum itself. For example, say I have an enum called "Season" which contains the values Spring, Summer, Autumn, and Winter, and it has a public method called next() which returns values()[(ordinal() + 1) % 4] Externally, no code ever sees the ordinal number, and there will never be additional members in this enum, so it seems like a valid use-case.
@DarrelHoffman My feeling is that doing that is fine, since the only strong arguments I see against using ordinal() hinge on far flung code being broken by changes to the enum enumeration constants. If you're going to modify the enum's constants you'd have to be in that file already. Most enums are fairly short, and if it's not you should be checking the file more thoroughly anyway. In both cases you should probably have a unit test covering your next() method anyway.
3

Maybe it's better to use a String representation than an integer, because the String is still valid if values are added to the enum. You can use the enum's name() method to convert the enum value to a String an the enum's valueOf() method to create an enum representation from the String again. The following example shows how to convert the enum value to String and back (ValueType is an enum):

ValueType expected = ValueType.FLOAT;
String value = expected.name();

System.out.println("Name value: " + value);

ValueType actual = ValueType.valueOf(value);

if(expected.equals(actual)) System.out.println("Values are equal");

Comments

3
public enum ProfileType {
PRIVATE,
PUBLIC
}

private ProfileType profileType = ProfileType.PRIVATE;

If you want to get int from profileType you can simply do:

int profileTypeInt = profileType.ordinal();

Comments

1
public enum Tax {

NONE(1), SALES(2), IMPORT(3);

private final int value;
    private Tax(int value) {
        this.value = value;
    }

    public String toString() {
        return Integer.toString(value);
    }
}

class Test {
    System.out.println(Tax.NONE);    //Just an example.
}

Comments

1

A somewhat different approach (at least on Android) is to use the IntDef annotation to combine a set of int constants

@IntDef({NOTAX, SALESTAX, IMPORTEDTAX})
@interface TAX {}
int NOTAX = 0;
int SALESTAX = 10;
int IMPORTEDTAX = 5;

Use as function parameter:

void computeTax(@TAX int taxPercentage){...} 

or in a variable declaration:

@TAX int currentTax = IMPORTEDTAX;

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.