adding default method changes interface initialization order?
Alex Buckley
alex.buckley at oracle.com
Wed Apr 23 18:47:38 UTC 2014
Paul, thanks. Nice little elongated diamond you have there!
Dan, Karen, looks like a significant under-specification and/or
over-implementation here. Thoughts?
Leonid, something to be aware of in the JCK coverage of default methods.
Alex
On 4/23/2014 1:36 AM, Paul Sandoz wrote:
>
> On Apr 22, 2014, at 11:23 PM, Alex Buckley <alex.buckley at Oracle.COM> wrote:
>
>> // Adding lambda-dev; follow-ups to both lists please.
>>
>> Default methods are not specified to cause any change in interface initialization. In principle the body of a default method can execute without the declaring interface having been initialized; if the body should touch a static field of the interface, then the interface must immediately be initialized.
>>
>> However, that behavior might be a surprise. So surprising, in fact, that HotSpot seems to be cautiously initializing superinterfaces in advance of the default method ever being invoked. JSR 335 people should comment on this. Are all superinterfaces initialized, or just those with default methods?
>>
>
> It appears to be all interfaces in the path traversed in the interface hierarchy up to and including the last superinterface declaring a default method. See example below that has a diamond pattern. The output is:
>
> #: initializing Test2$J
> #: initializing Test2$JN
> #: initializing Test2$L
> 4
>
> Comment out the default method on J and uncomment that on K and interfaces in the other path are initialized:
>
> #: initializing Test2$K
> #: initializing Test2$KN
> #: initializing Test2$L
> 4
>
> If a default method is only declared on I then all interfaces get initialized.
>
> #: initializing Test2$I
> #: initializing Test2$J
> #: initializing Test2$JN
> #: initializing Test2$K
> #: initializing Test2$KN
> #: initializing Test2$L
> 4
>
> Paul.
>
>> In addition, if the default method body invokes a static method of the interface, then initialization must occur - yet JLS8 12.4.1 does not require it ("T is a class and a static method declared by T is invoked.") That's a straight spec bug - but note that specifying superinterface initialization due to default methods will make it moot.
>>
>> Alex
>>
>
> public class Test2 {
>
> interface I {
> int v = Test2.out(I.class, 1);
>
> // default void x() {}
> }
>
> interface J extends I {
> int v = Test2.out(J.class, 2);
>
> default void x() {}
> }
>
> interface JN extends J {
> int v = Test2.out(JN.class, 2);
> }
>
> interface K extends I {
> int v = Test2.out(K.class, 3);
>
> // default void x() {}
> }
>
> interface KN extends K {
> int v = Test2.out(KN.class, 3);
> }
>
> interface L extends JN, KN {
> int v = Test2.out(L.class, 4);
>
> // default void x() {}
> }
>
> public static void main(String[] args) {
> System.out.println(L.v);
> }
>
> static int out(Class c, int i) {
> System.out.println("#: initializing " + c.getName());
> return i;
> }
>
> }
>
More information about the lambda-dev
mailing list