Inside a Java enumerated class, I’d like to create a final static array containing the values() of the class. When I do this along the following lines, the resulting array is null.
public enum Name {
E1( stuff ), E2( stuff );
private static final Name[] values = Name.values();
private Name( stuff ) { more stuff; }
}
I’ve also tried doing this by calling an explicit class setter method, but this gave an java.lang.ExceptionInInitializerError exception.
I understand the problem is caused by some shallow dependencies as the stuff in the previous code uses other classes, which themselves depend on the enumerated class.
Is there a tested and proven technique to achieve what I need?
tl;dr: what you’re trying to do isn’t possible – static fields of an enum type don’t get initialized until after all the constructor calls have completed.
Consider this example:
Note that the reason for the existence of the
dumpmethod is that it is a compile-time error (Java Language Spec section 8.9.2) to try and reference thevaluefield from inside the constructor ofName. With this test harness:we get
Decompiling the
Nameclass withjavapwe see the following:The compiler creates a private field
$VALUESholding the value array, and thevalues()method is implemented as{ return (Name[])$VALUES.clone() }. So how does$VALUESget initialized?What we see here is that the initialization essentially does:
so during the execution of the constructor calls, the
valuesfield will be null and thevalues()method will throw a NullPointerException (which will get wrapped in an ExceptionInInitializerError).