I have created an Enum to define certain actions. Programming against a external API I am forced to use an Integer
to express this action. That's why I have added an integer instance field to my Enum. This should be d'accord with Joshua Bloch's Effective Java, instead of relying on ordinal()
or the order of the Enum constants using values()[index]
.
public enum Action {
START(0),
QUIT(1);
public final int code;
Protocol(int code) {
this.code = code;
}
}
I get an integer value what
from the API and now I want to create an Enum value out of it, how can I implement this in the most generic fashion?
Obviously, adding such a factory method, will not work. You cannot instantiate an Enum.
Action valueOf(int what) {
return new Action(what);
}
Of course, I can always make a switch-case statement and add all the possible codes and return the appropriate constant. But I want to avoid defining them in two places at the same time.
As we have learned, we cannot inherit enum classes in Java. However, enum classes can implement interfaces.
The Java compiler internally adds the valueOf() method when it creates an enum. The valueOf() method returns the value of given constant enum.
The Enum constructor can accept multiple values. Moreover, we can add computed values to our enum by adding methods to perform operations.
An enum declaration is implicitly final unless it contains at least one enum constant that has a class body. A nested enum type is implicitly static. It is permitted for the declaration of a nested enum type to redundantly specify the static modifier.
If you're going to have a lot of them, you can use a HashMap<Integer, Action>
:
private static final Map<Integer, Action> actions = new HashMap<>(values().size, 1);
static {
for (Action action : values())
actions.put(action.code, action);
}
// ...
public static Action valueOf(int what) {
return actions.get(what);
}
This is useful if you're going to have a large number of Action
values since the HashMap
lookup is O(1).
If you are sure that your codes will always be sequential and starting from 0 then the most efficient option would be
public enum Action {
START(0),
QUIT(1);
public static final Action[] ACTIONS;
static {
ACTIONS = new Action[values().length];
for(Action a : values()) {
ACTIONS[a.code] = a;
}
}
public final int code;
Protocol(int code) {
this.code = code;
}
}
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