adding default method changes interface initialization order?

Stuart Marks stuart.marks at oracle.com
Tue Apr 22 20:24:20 UTC 2014


Hi all,

It seems like the presence of a default method in an interface will change the 
timing of when that interface is initialized.

Interface initialization is covered by JLS 12.4.1 [1]. Example 12.4.1-3 
illustrates this:

     interface I {
         int i = 1, ii = Test.out("ii", 2);
     }
     interface J extends I {
         int j = Test.out("j", 3), jj = Test.out("jj", 4);
     }
     interface K extends J {
         int k = Test.out("k", 5);
     }
     class Test {
         public static void main(String[] args) {
             System.out.println(J.i);
             System.out.println(K.j);
         }
         static int out(String s, int i) {
             System.out.println(s + "=" + i);
             return i;
         }
     }

The expected output is:

     1
     j=3
     jj=4
     3

Indeed, I get the expected output for the example as it stands. However, if a 
default method is added to interface I, the behavior of the program changes. 
Consider:

     interface I {
         int i = 1, ii = Test.out("ii", 2);
         default void method() { } // causes initialization!
     }

The output changes to:

     1
     ii=2
     j=3
     jj=4
     3

That is, the "ii=2" line indicates that interface I has now been initialized 
where it hadn't been before. The mere presence of a default method seems to 
trigger the change, even if the default method is never called, referenced, or 
overridden.

Is this a bug?

(Hat tip to Sotirios Delimanolis for asking this on StackOverflow. [2])

s'marks


[1] http://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1

[2] 
http://stackoverflow.com/questions/23096084/when-is-an-interface-with-a-default-method-initialized


s'marks


More information about the compiler-dev mailing list