United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-8043189 : 12.4.1: Should asserts trigger initialization of outer classes?

Details
Type:
Bug
Submit Date:
2014-05-14
Status:
Resolved
Updated Date:
2016-09-27
Project Name:
JDK
Resolved Date:
2016-09-27
Component:
specification
OS:
Sub-Component:
language
CPU:
Priority:
P5
Resolution:
Fixed
Affected Versions:
8
Fixed Versions:
9

Related Reports
Relates:

Sub Tasks

Description
Since JLS 3, 12.4.1 has included a rule for performing static initialization of top-level classes when an assert statement is executed:

"T is a top-level class, and an assert statement (??14.10) lexically nested within T is executed."

I am unable to reproduce this behavior:

-----
public class AssertInClass {
   public static final java.io.PrintStream s = System.out.printf("initializing\n");

   public static class C {

       public void foo() { assert System.out.printf("foo assert\n") != null; }

       public static void main(String... args) {
           assert System.out.printf("main assert\n") != null;
           new C().foo();
           //new AssertInClass(); // uncommenting triggers initialization
           System.out.println("done");
       }
   }

}

$ -> java7 -ea AssertInClass\$C
main assert
foo assert
done
// initialization never happens
-----

JVMS 5.5 does not directly account for this circumstance, so I assume the JLS rule was written with a certain implementation strategy in mind that would require some sort of access to the (initialized) outer class.  It appears that this implementation strategy is not used, and perhaps never was.

I'd appreciate better historical context, but from what I can tell, it looks like this rule is simply wrong and should be removed.
                                    

Comments
The assumption in the Description is correct -- JLS3 14.10 was specified to align with a javac implementation strategy that was never used, i.e. "An assert statement causes the enclosing top level class (if it exists) to be initialized, if it has not already been initialized (12.4.1)." Matters were clarified in JLS7 but the stray assert-causes-initialization clause remained in 12.4.1.

                                     
2015-09-23



Hardware and Software, Engineered to Work Together