Eager enum class initialization with enum switch
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Feb 20 11:23:57 UTC 2019
Hi Tagir,
as you might know, we have plans to overhaul switch translation strategy:
https://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000522.html
Which, I think, should take care of fixing this particular issue. I
think aiming for that plan is better than coming up with a point fix for
this specific corner case.
Cheers
Maurizio
On 20/02/2019 05:24, Tagir Valeev wrote:
> 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