Reputation: 8620
I stumbled upon a very weird bug and I can't explain why it happens. Imagine the following enum:
import java.awt.Color;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(MyEnum.CONSTANT1.get());
System.out.println(MyEnum.CONSTANT2.get());
}
private enum MyEnum {
CONSTANT1(staticMethod1()),
CONSTANT2(staticMethod2());
private static final Color WHY_AM_I_NULL = new Color(255, 255, 255);
private final Color color;
private MyEnum(Color color) {
this.color = color;
}
public Color get() {
return color;
}
private static Color staticMethod1() {
return new Color(100, 100, 100);
}
private static Color staticMethod2() {
return WHY_AM_I_NULL;
}
}
}
The results when you run this are:
java.awt.Color[r=100,g=100,b=100]
null
The question is, why the second one is null?
Ammendment: If you put the WHY_AM_I_NULL in a private static class inside the enum, then it is initialized first.
Upvotes: 10
Views: 7288
Reputation: 11433
The problem is that all static fields (and enum instances count as such) are initialized in their declared order (specification). So when CONSTANT2
is instantiated, the field WHY_AM_I_NULL
is still not initialized (and therefore null
).
As you can't put the field before the enum instances, you have to find some other way of doing what you want (e.g., putting the field outside the enum class). If you tell us, what you really want to accomplish, one could make further suggestions.
Edit: If you put WHY_AM_I_NULL
in a nested class, the fields of this class will be initialized as soon as the class is first accessed (i.e., in this case during the execution of staticMethod2
).
Upvotes: 14
Reputation: 6211
WHY_AM_I_NULL
is null when staticMethod2 is invoked - this is how JLS specifies initialization
In a different sequence you'd get 100, 255
instead of 100, null
:
private static final Color WHY_AM_I_NULL = new Color(255, 255, 255);
private enum MyEnum {
CONSTANT1(staticMethod1()),
CONSTANT2(staticMethod2());
//...
Upvotes: 2
Reputation: 13310
This is because the static fields (including enum values) are initialized in the order they appear in the file.
So CONSTANT1
, and CONSTANT2
get initialized before WHY_AM_I_NULL
, therefore CONSTANT2
is initialized with null
.
Upvotes: 1
Reputation: 115328
Enums are the compiler feature. Actually compiler creates class named MyEnum that contains 2 public static fields CONSTANT1 and CONSTANT2 and other code.
Static initialization is done up-to-down, so the CONSTANT2 is created and is initialized before static variable WHY_AM_I_NULL. This is why WHY_AM_I_NULL is null when CONSTANT2 is being initialized.
Upvotes: 4