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?
Can you provide an example where this happens because it shouldn't be null.
prints
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
dump
method is that it is a compile-time error (Java Language Spec section 8.9.2) to try and reference thevalue
field from inside the constructor ofName
. With this test harness:we get
Decompiling the
Name
class withjavap
we see the following:The compiler creates a private field
$VALUES
holding the value array, and thevalues()
method is implemented as{ return (Name[])$VALUES.clone() }
. So how does$VALUES
get initialized?What we see here is that the initialization essentially does:
so during the execution of the constructor calls, the
values
field will be null and thevalues()
method will throw a NullPointerException (which will get wrapped in an ExceptionInInitializerError).