Please look at this link. In his book Effective Java, Joshua Bloch says
Note that the Operation constants are put into the stringToEnum map from a static block that runs after the constants have been created.
Trying to make each constant put itself into the map from its own constructor would cause a compilation error
. This is a good thing, because it would cause a NullPointerException if it were legal.
Enum constructors aren’t permitted to access the enum’s static fields, except for compile-time constant fields.
This restriction is necessary because these static fields have not yet been initialized when the constructors run.
I have two questions
Thanks
As for first question: you cannot have separate constructors, but you can work-around this in the following manner:
public enum EnumTest {
ONE() {
void init() {
val = 2;
}
},
TWO() {
void init() {
val = 1;
}
};
protected int val;
abstract void init();
EnumTest() {
init();
}
}
This way you technically have separate initialization methods for different constants.
Another way is to use initializer sections:
public enum EnumTest {
ONE() {{
val = 2;
}},
TWO() {{
val = 1;
}};
protected int val;
}
As for your second question: constant fields are not accessible during enum construction, because enum constants are accessible for static fields. For example, this code compiles correctly:
public enum EnumTest {
ONE, TWO;
public static final String ONE_STRING = ONE.toString();
}
If accessing ONE_STRING from the constructor were allowed, you would either had an endless initialization loop or accessing of not-yet-initialized enum constant.