Eager enum class initialization with enum switch

Alex Buckley alex.buckley at oracle.com
Tue Feb 19 21:38:40 UTC 2019


On 2/16/2019 12:59 AM, Tagir Valeev wrote:
> Consider the following program (Test.java):
>
> class Test {
>    enum A{
>      X;
>      static { System.out.println("A is initialized!"); }
>    }
>    enum B{
>      Y;
>      static { System.out.println("B is initialized!"); }
>    }
>
>    static void testA(A a) { switch(a) {} }
>
>    static void testB(B b) { switch(b) {} }
>
>    public static void main(String[] args) {
>      testA(A.X);
>    }
> }
>
> When I compile it via javac and run it I see:
> A is initialized!
> B is initialized!
>
> Despite the fact that testB is never called, and no references to the
> B enum actually used during the program execution. According to JLS
> 12.4.1 B should not be initialized. Am I missing something?

Using JDK 11, I agree that compiling and running Test produces the 
results you say.

It's not valid to initialize the enum type B when no reference to B's 
constants or methods is made at run time. I vaguely recall prior 
discussions of this unfortunate aspect of javac's translation.

I notice that the presence of the `testB(B)` method is what triggers 
javac's overly eager initialization of B. Without that method 
declaration, only "A is initialized!" is printed.

Alex


More information about the compiler-dev mailing list