Is there any way of converting an enum into a constant expression? I want my switch operator to choose among the values of an enum, but I got a compile error "case expressions must be constant expressions", so I tried to declare it in a variable:
final int REG = MyEnum.REG.getIndex().intValue();
switch (service.getIndex()) {
case REG:
But I still get the same error. According to Oracle's documentation http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:
•Literals of primitive type and literals of type String
So it isn't working because I'm not using a literal. I think I will have to declare it as:
final int REG = 8;
But it'd be much better to link it to the enum. Is there any way of doing this?
EDIT
Turns out I don't need to use any final variable. It is just as simple as:
switch (service) {
case REG:
It didn't occur to me till I saw Andrea's comment. Thanks for your answers.
Because they are constants, the names of an enum type's fields are in uppercase letters. You should use enum types any time you need to represent a fixed set of constants.
Enums are lists of constants. When you need a predefined list of values which do represent some kind of numeric or textual data, you should use an enum. You should always use enums when a variable (especially a method parameter) can only take one out of a small set of possible values.
valueOf. Returns the enum constant of the specified enum type with the specified name. The name must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)
TryParse() method converts the string representation of enum member name or numeric value to an equivalent enum object. The Enum. TryParse() method returns a boolean to indicate whether the specified string is converted to enum or not. Returns true if the conversion succeeded; otherwise, returns false .
If possible, modify your getIndex()
method so that it returns an enum instead of an integer. If this is not possible, you need to map the index to an enum element:
Given the following enum:
public enum Index {
ONE,
TWO,
THREE
}
you can map your index to an enum element by using
Index.values()[index]
Given your method Integer getIndex()
, you can then do something like
switch(Index.values()[getIndex()])
case ONE : ...
break;
case TWO : ...
break;
case THREE : ...
break;
}
Note that this might throw an ArrayIndexOutOfBoundsException
if you try to access an index within the enum which is larger than the number of enum elements (e.g. in the sample above, if getIndex()
returns a value > 2).
I would encapsulate the expression Index.values()[getIndex()]
into an enum method like valueOf(int index)
, similar to the default valueOf(String s)
. You can then also handle the valid array index check there (and for example return a special enum value if the index is out of range). Similarly, you can then also convert discrete values which have special meanings:
public enum Index {
ZERO,
ONE,
TWO,
THREE,
REG,
INVALID;
public static Index valueOf(int index) {
if (index == 8) {
return REG;
}
if (index >= values().length) {
return INVALID;
}
return values()[index];
}
}
This is an example only - in any case, it generally depends on the range of values you get from your getIndex()
method, and how you want to map them to the enum elements.
You can then use it like
switch(Index.valueOf(service.getIndex())) {
case ZERO : ... break;
...
case REG : ... break;
...
}
See also Cast Int to enum in Java for some additional information (especially the hint that values()
is an expensive operation since it needs to return a copy of the array each time it is called).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With