Eager enum class initialization with enum switch
Tagir Valeev
amaembo at gmail.com
Wed Feb 20 05:24:23 UTC 2019
Hello, Alex!
Thanks for reply. I filed an issue:
https://bugs.openjdk.java.net/browse/JDK-8219412
It would be great were the lookup table created using condy bootstrap.
This would not only fix the reported problem,
but also reduce the amount of produced code. In particular, no
additional class file would be necessary:
bootstrap methods could be generated in the same class (one bootstrap
and one constant per enum; the same constant
could be reused for several switches over the same enum).
With best regards,
Tagir Valeev
On Wed, Feb 20, 2019 at 5:09 AM Alex Buckley <alex.buckley at oracle.com> wrote:
>
> 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