When is an interface with a default method initialized?












92














While searching through the Java Language Specification to answer this question, I learned that




Before a class is initialized, its direct superclass must be
initialized, but interfaces implemented by the class are not
initialized.
Similarly, the superinterfaces of an interface are not
initialized before the interface is initialized.




For my own curiosity, I tried it and, as expected, the interface InterfaceType was not initialized.



public class Example {
public static void main(String args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}

class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}

class ClassInitializer {
static {
System.out.println("static initializer");
}
}

interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public void method();
}


This program prints



implemented method


However, if the interface declares a default method, then initialization does occur. Consider the InterfaceType interface given as



interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public default void method() {
System.out.println("default method");
}
}


then the same program above would print



static initializer  
implemented method


In other words, the static field of the interface is initialized (step 9 in the Detailed Initialization Procedure) and the static initializer of the type being initialized is executed. This means that the interface was initialized.



I could not find anything in the JLS to indicate that this should happen. Don't get me wrong, I understand that this should happen in case the implementing class doesn't provide an implementation for the method, but what if it does? Is this condition missing from the Java Language Specification, did I miss something, or am I interpreting it wrongly?










share|improve this question




















  • 4




    My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
    – Alexey Malev
    Apr 15 '14 at 23:04










  • It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
    – Warren Dew
    Apr 20 '14 at 5:50






  • 1




    Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
    – NeverGiveUp161
    May 9 '14 at 9:54










  • I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
    – MaxZoom
    May 20 '15 at 22:04










  • @MaxZoom Java 8 allows default methods.
    – Sotirios Delimanolis
    May 20 '15 at 22:13
















92














While searching through the Java Language Specification to answer this question, I learned that




Before a class is initialized, its direct superclass must be
initialized, but interfaces implemented by the class are not
initialized.
Similarly, the superinterfaces of an interface are not
initialized before the interface is initialized.




For my own curiosity, I tried it and, as expected, the interface InterfaceType was not initialized.



public class Example {
public static void main(String args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}

class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}

class ClassInitializer {
static {
System.out.println("static initializer");
}
}

interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public void method();
}


This program prints



implemented method


However, if the interface declares a default method, then initialization does occur. Consider the InterfaceType interface given as



interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public default void method() {
System.out.println("default method");
}
}


then the same program above would print



static initializer  
implemented method


In other words, the static field of the interface is initialized (step 9 in the Detailed Initialization Procedure) and the static initializer of the type being initialized is executed. This means that the interface was initialized.



I could not find anything in the JLS to indicate that this should happen. Don't get me wrong, I understand that this should happen in case the implementing class doesn't provide an implementation for the method, but what if it does? Is this condition missing from the Java Language Specification, did I miss something, or am I interpreting it wrongly?










share|improve this question




















  • 4




    My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
    – Alexey Malev
    Apr 15 '14 at 23:04










  • It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
    – Warren Dew
    Apr 20 '14 at 5:50






  • 1




    Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
    – NeverGiveUp161
    May 9 '14 at 9:54










  • I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
    – MaxZoom
    May 20 '15 at 22:04










  • @MaxZoom Java 8 allows default methods.
    – Sotirios Delimanolis
    May 20 '15 at 22:13














92












92








92


36





While searching through the Java Language Specification to answer this question, I learned that




Before a class is initialized, its direct superclass must be
initialized, but interfaces implemented by the class are not
initialized.
Similarly, the superinterfaces of an interface are not
initialized before the interface is initialized.




For my own curiosity, I tried it and, as expected, the interface InterfaceType was not initialized.



public class Example {
public static void main(String args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}

class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}

class ClassInitializer {
static {
System.out.println("static initializer");
}
}

interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public void method();
}


This program prints



implemented method


However, if the interface declares a default method, then initialization does occur. Consider the InterfaceType interface given as



interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public default void method() {
System.out.println("default method");
}
}


then the same program above would print



static initializer  
implemented method


In other words, the static field of the interface is initialized (step 9 in the Detailed Initialization Procedure) and the static initializer of the type being initialized is executed. This means that the interface was initialized.



I could not find anything in the JLS to indicate that this should happen. Don't get me wrong, I understand that this should happen in case the implementing class doesn't provide an implementation for the method, but what if it does? Is this condition missing from the Java Language Specification, did I miss something, or am I interpreting it wrongly?










share|improve this question















While searching through the Java Language Specification to answer this question, I learned that




Before a class is initialized, its direct superclass must be
initialized, but interfaces implemented by the class are not
initialized.
Similarly, the superinterfaces of an interface are not
initialized before the interface is initialized.




For my own curiosity, I tried it and, as expected, the interface InterfaceType was not initialized.



public class Example {
public static void main(String args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
foo.method();
}
}

class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}

class ClassInitializer {
static {
System.out.println("static initializer");
}
}

interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public void method();
}


This program prints



implemented method


However, if the interface declares a default method, then initialization does occur. Consider the InterfaceType interface given as



interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public default void method() {
System.out.println("default method");
}
}


then the same program above would print



static initializer  
implemented method


In other words, the static field of the interface is initialized (step 9 in the Detailed Initialization Procedure) and the static initializer of the type being initialized is executed. This means that the interface was initialized.



I could not find anything in the JLS to indicate that this should happen. Don't get me wrong, I understand that this should happen in case the implementing class doesn't provide an implementation for the method, but what if it does? Is this condition missing from the Java Language Specification, did I miss something, or am I interpreting it wrongly?







java interface java-8 default-method






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 16:12

























asked Apr 15 '14 at 23:02









Sotirios Delimanolis

207k39476568




207k39476568








  • 4




    My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
    – Alexey Malev
    Apr 15 '14 at 23:04










  • It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
    – Warren Dew
    Apr 20 '14 at 5:50






  • 1




    Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
    – NeverGiveUp161
    May 9 '14 at 9:54










  • I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
    – MaxZoom
    May 20 '15 at 22:04










  • @MaxZoom Java 8 allows default methods.
    – Sotirios Delimanolis
    May 20 '15 at 22:13














  • 4




    My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
    – Alexey Malev
    Apr 15 '14 at 23:04










  • It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
    – Warren Dew
    Apr 20 '14 at 5:50






  • 1




    Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
    – NeverGiveUp161
    May 9 '14 at 9:54










  • I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
    – MaxZoom
    May 20 '15 at 22:04










  • @MaxZoom Java 8 allows default methods.
    – Sotirios Delimanolis
    May 20 '15 at 22:13








4




4




My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
– Alexey Malev
Apr 15 '14 at 23:04




My guess would be - such interfaces considered abstract classes in terms of initialization order. I wrote this as a comment as I'm not sure whether this is correct statement :)
– Alexey Malev
Apr 15 '14 at 23:04












It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
– Warren Dew
Apr 20 '14 at 5:50




It should be in section 12.4 of the JLS, but does not appear to be there. I'd say it's missing.
– Warren Dew
Apr 20 '14 at 5:50




1




1




Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
– NeverGiveUp161
May 9 '14 at 9:54




Nevermind....most of the time when they don't understand or do not have an explanation they will downvote :( .This happens on SO generally.
– NeverGiveUp161
May 9 '14 at 9:54












I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
– MaxZoom
May 20 '15 at 22:04




I thought that interface in Java should not define any concrete method. So I am surprise that InterfaceType code has compiled.
– MaxZoom
May 20 '15 at 22:04












@MaxZoom Java 8 allows default methods.
– Sotirios Delimanolis
May 20 '15 at 22:13




@MaxZoom Java 8 allows default methods.
– Sotirios Delimanolis
May 20 '15 at 22:13












4 Answers
4






active

oldest

votes


















80





+250









This is a very interesting issue!



It seems like JLS section 12.4.1 ought to cover this definitively. However, the behavior of Oracle JDK and OpenJDK (javac and HotSpot) differs from what's specified here. In particular, the Example 12.4.1-3 from this section covers interface initialization. The example as follows:



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;
}
}


Its expected output is:



1
j=3
jj=4
3


and indeed I get the expected output. However, if a default method is added to interface I,



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


which clearly indicates that interface I is being initialized where it wasn't before! The mere presence of the default method is enough to trigger the initialization. The default method doesn't have to be called or overridden or even mentioned, nor does the presence of an abstract method trigger initialization.



My speculation is that the HotSpot implementation wanted to avoid adding class/interface initialization checking into the critical path of the invokevirtual call. Prior to Java 8 and default methods, invokevirtual could never end up executing code in an interface, so this didn't arise. One might think this is part of the class/interface preparation stage (JLS 12.3.2) which initializes things like method tables. But perhaps this went too far and accidentally did full initialization instead.



I've raised this question on the OpenJDK compiler-dev mailing list. There's been a reply from Alex Buckley (editor of the JLS) in which he raises more questions directed at the JVM and lambda implementation teams. He also notes that there's a bug in the spec here where it says "T is a class and a static method declared by T is invoked" should also apply if T is an interface. So, it might be that there are both specification and HotSpot bugs here.



Disclosure: I work for Oracle on OpenJDK. If people think this gives me an unfair advantage at getting the bounty attached to this question, I'm willing to be flexible about it.






share|improve this answer



















  • 6




    I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
    – Sotirios Delimanolis
    Apr 22 '14 at 22:40






  • 44




    @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
    – assylias
    Apr 23 '14 at 0:16






  • 2




    A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
    – Marco13
    Apr 23 '14 at 9:38






  • 2




    @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
    – Stuart Marks
    Apr 25 '14 at 1:45






  • 1




    @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
    – Stuart Marks
    May 29 '15 at 0:11



















13














The interface is not initialized because the constant field InterfaceType.init , which is being initialized by non constant value (method call), is not used anywhere.



It is known at compile time that constant field of interface is not used anywhere, and the interface is not containing any default method (In java-8) so there is no need to initialize or load the interface.



Interface will be initialized in following cases,




  • constant field is used in your code.

  • Interface contains a default method (Java 8)


In case of Default Methods, You are implementing InterfaceType. So, If InterfaceType will contain any default methods, It will be INHERITED (used) in implementing class. And Initialization will be into the picture.



But, If you are accessing constant field of interface (which is initialized in normal way), The interface initialization is not required.



Consider following code.



public class Example {
public static void main(String args) throws Exception {
InterfaceType foo = new InterfaceTypeImpl();
System.out.println(InterfaceType.init);
foo.method();
}
}

class InterfaceTypeImpl implements InterfaceType {
@Override
public void method() {
System.out.println("implemented method");
}
}

class ClassInitializer {
static {
System.out.println("static initializer");
}
}

interface InterfaceType {
public static final ClassInitializer init = new ClassInitializer();

public void method();
}


In above case, Interface will be initialized and loaded because you are using the field InterfaceType.init.



I am not giving the default method example as you already given that in your question.



Java language specification and example is given in JLS 12.4.1 (Example does not contain default methods.)





I can not find JLS for Default methods, there may be two possibilities




  • Java people forgot to consider the case of default method. (Specification Doc bug.)

  • They just refer the default methods as non-constant member of
    interface. (But mentioned no where, again Specification Doc bug.)






share|improve this answer























  • I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
    – Sotirios Delimanolis
    Apr 16 '14 at 13:52










  • @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
    – Not a bug
    Apr 16 '14 at 16:38










  • Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
    – Sotirios Delimanolis
    Apr 16 '14 at 16:45










  • I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
    – Not a bug
    Apr 16 '14 at 17:41






  • 1




    @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
    – Lokesh
    Apr 18 '14 at 3:45



















10














The instanceKlass.cpp file from the OpenJDK contains the initialization method InstanceKlass::initialize_impl that corresponds to the Detailed Initialization Procedure in the JLS, which is analogously found in the Initialization section in the JVM Spec.



It contains a new step that is not mentioned in the JLS and not in the JVM book that is referred to in the code:



// refer to the JVM book page 47 for description of steps
...

if (this_oop->has_default_methods()) {
// Step 7.5: initialize any interfaces which have default methods
for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
Klass* iface = this_oop->local_interfaces()->at(i);
InstanceKlass* ik = InstanceKlass::cast(iface);
if (ik->has_default_methods() && ik->should_be_initialized()) {
ik->initialize(THREAD);
....
}
}
}


So this initialization has been implemented explicitly as a new Step 7.5. This indicates that this implementation followed some specification, but it seems that the written specification on the website has not been updated accordingly.



EDIT: As a reference, the commit (from October 2012!) where the respective step has been included in the implementation: http://hg.openjdk.java.net/jdk8/build/hotspot/rev/4735d2c84362



EDIT2: Coincidentally, I found this Document about default methods in hotspot which contains an interesting side note at the end:




3.7 Miscellaneous



Because interfaces now have bytecode in them, we must initialize them at the
time that an implementing class is initialized.







share|improve this answer



















  • 1




    Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
    – Stuart Marks
    Apr 25 '14 at 1:47



















1














I'll try to make a case that an interface initialization should not cause any side-channel side effects that the subtypes depend on, therefore, whether this is a bug or not, or whichever way the Java fixes it, it should not matter to the application in which order interfaces are initialized.



In the case of a class, it is well accepted that it can cause side effects that subclasses depend on. For example



class Foo{
static{
Bank.deposit($1000);
...


Any subclass of Foo would expect that they'll see $1000 in the bank, anywhere in the subclass code. Therefore the superclass is initialized prior to the subclass.



Shouldn't we do the same thing for superintefaces as well? Unfortunately, the order of superinterfaces are not supposed to be significant, therefore there is no well defined order in which to initialize them.



So we better not establish this kind of side effects in interface initializations. After all, interface is not meant for these features (static fields/methods) we pile on for convenience.



Therefore if we follow that principle, it'll be no concern to us in which order interfaces are initialized.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f23096084%2fwhen-is-an-interface-with-a-default-method-initialized%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    80





    +250









    This is a very interesting issue!



    It seems like JLS section 12.4.1 ought to cover this definitively. However, the behavior of Oracle JDK and OpenJDK (javac and HotSpot) differs from what's specified here. In particular, the Example 12.4.1-3 from this section covers interface initialization. The example as follows:



    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;
    }
    }


    Its expected output is:



    1
    j=3
    jj=4
    3


    and indeed I get the expected output. However, if a default method is added to interface I,



    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


    which clearly indicates that interface I is being initialized where it wasn't before! The mere presence of the default method is enough to trigger the initialization. The default method doesn't have to be called or overridden or even mentioned, nor does the presence of an abstract method trigger initialization.



    My speculation is that the HotSpot implementation wanted to avoid adding class/interface initialization checking into the critical path of the invokevirtual call. Prior to Java 8 and default methods, invokevirtual could never end up executing code in an interface, so this didn't arise. One might think this is part of the class/interface preparation stage (JLS 12.3.2) which initializes things like method tables. But perhaps this went too far and accidentally did full initialization instead.



    I've raised this question on the OpenJDK compiler-dev mailing list. There's been a reply from Alex Buckley (editor of the JLS) in which he raises more questions directed at the JVM and lambda implementation teams. He also notes that there's a bug in the spec here where it says "T is a class and a static method declared by T is invoked" should also apply if T is an interface. So, it might be that there are both specification and HotSpot bugs here.



    Disclosure: I work for Oracle on OpenJDK. If people think this gives me an unfair advantage at getting the bounty attached to this question, I'm willing to be flexible about it.






    share|improve this answer



















    • 6




      I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
      – Sotirios Delimanolis
      Apr 22 '14 at 22:40






    • 44




      @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
      – assylias
      Apr 23 '14 at 0:16






    • 2




      A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
      – Marco13
      Apr 23 '14 at 9:38






    • 2




      @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
      – Stuart Marks
      Apr 25 '14 at 1:45






    • 1




      @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
      – Stuart Marks
      May 29 '15 at 0:11
















    80





    +250









    This is a very interesting issue!



    It seems like JLS section 12.4.1 ought to cover this definitively. However, the behavior of Oracle JDK and OpenJDK (javac and HotSpot) differs from what's specified here. In particular, the Example 12.4.1-3 from this section covers interface initialization. The example as follows:



    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;
    }
    }


    Its expected output is:



    1
    j=3
    jj=4
    3


    and indeed I get the expected output. However, if a default method is added to interface I,



    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


    which clearly indicates that interface I is being initialized where it wasn't before! The mere presence of the default method is enough to trigger the initialization. The default method doesn't have to be called or overridden or even mentioned, nor does the presence of an abstract method trigger initialization.



    My speculation is that the HotSpot implementation wanted to avoid adding class/interface initialization checking into the critical path of the invokevirtual call. Prior to Java 8 and default methods, invokevirtual could never end up executing code in an interface, so this didn't arise. One might think this is part of the class/interface preparation stage (JLS 12.3.2) which initializes things like method tables. But perhaps this went too far and accidentally did full initialization instead.



    I've raised this question on the OpenJDK compiler-dev mailing list. There's been a reply from Alex Buckley (editor of the JLS) in which he raises more questions directed at the JVM and lambda implementation teams. He also notes that there's a bug in the spec here where it says "T is a class and a static method declared by T is invoked" should also apply if T is an interface. So, it might be that there are both specification and HotSpot bugs here.



    Disclosure: I work for Oracle on OpenJDK. If people think this gives me an unfair advantage at getting the bounty attached to this question, I'm willing to be flexible about it.






    share|improve this answer



















    • 6




      I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
      – Sotirios Delimanolis
      Apr 22 '14 at 22:40






    • 44




      @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
      – assylias
      Apr 23 '14 at 0:16






    • 2




      A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
      – Marco13
      Apr 23 '14 at 9:38






    • 2




      @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
      – Stuart Marks
      Apr 25 '14 at 1:45






    • 1




      @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
      – Stuart Marks
      May 29 '15 at 0:11














    80





    +250







    80





    +250



    80




    +250




    This is a very interesting issue!



    It seems like JLS section 12.4.1 ought to cover this definitively. However, the behavior of Oracle JDK and OpenJDK (javac and HotSpot) differs from what's specified here. In particular, the Example 12.4.1-3 from this section covers interface initialization. The example as follows:



    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;
    }
    }


    Its expected output is:



    1
    j=3
    jj=4
    3


    and indeed I get the expected output. However, if a default method is added to interface I,



    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


    which clearly indicates that interface I is being initialized where it wasn't before! The mere presence of the default method is enough to trigger the initialization. The default method doesn't have to be called or overridden or even mentioned, nor does the presence of an abstract method trigger initialization.



    My speculation is that the HotSpot implementation wanted to avoid adding class/interface initialization checking into the critical path of the invokevirtual call. Prior to Java 8 and default methods, invokevirtual could never end up executing code in an interface, so this didn't arise. One might think this is part of the class/interface preparation stage (JLS 12.3.2) which initializes things like method tables. But perhaps this went too far and accidentally did full initialization instead.



    I've raised this question on the OpenJDK compiler-dev mailing list. There's been a reply from Alex Buckley (editor of the JLS) in which he raises more questions directed at the JVM and lambda implementation teams. He also notes that there's a bug in the spec here where it says "T is a class and a static method declared by T is invoked" should also apply if T is an interface. So, it might be that there are both specification and HotSpot bugs here.



    Disclosure: I work for Oracle on OpenJDK. If people think this gives me an unfair advantage at getting the bounty attached to this question, I'm willing to be flexible about it.






    share|improve this answer














    This is a very interesting issue!



    It seems like JLS section 12.4.1 ought to cover this definitively. However, the behavior of Oracle JDK and OpenJDK (javac and HotSpot) differs from what's specified here. In particular, the Example 12.4.1-3 from this section covers interface initialization. The example as follows:



    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;
    }
    }


    Its expected output is:



    1
    j=3
    jj=4
    3


    and indeed I get the expected output. However, if a default method is added to interface I,



    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


    which clearly indicates that interface I is being initialized where it wasn't before! The mere presence of the default method is enough to trigger the initialization. The default method doesn't have to be called or overridden or even mentioned, nor does the presence of an abstract method trigger initialization.



    My speculation is that the HotSpot implementation wanted to avoid adding class/interface initialization checking into the critical path of the invokevirtual call. Prior to Java 8 and default methods, invokevirtual could never end up executing code in an interface, so this didn't arise. One might think this is part of the class/interface preparation stage (JLS 12.3.2) which initializes things like method tables. But perhaps this went too far and accidentally did full initialization instead.



    I've raised this question on the OpenJDK compiler-dev mailing list. There's been a reply from Alex Buckley (editor of the JLS) in which he raises more questions directed at the JVM and lambda implementation teams. He also notes that there's a bug in the spec here where it says "T is a class and a static method declared by T is invoked" should also apply if T is an interface. So, it might be that there are both specification and HotSpot bugs here.



    Disclosure: I work for Oracle on OpenJDK. If people think this gives me an unfair advantage at getting the bounty attached to this question, I'm willing to be flexible about it.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Apr 23 '14 at 14:21

























    answered Apr 22 '14 at 22:04









    Stuart Marks

    79.1k25135203




    79.1k25135203








    • 6




      I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
      – Sotirios Delimanolis
      Apr 22 '14 at 22:40






    • 44




      @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
      – assylias
      Apr 23 '14 at 0:16






    • 2




      A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
      – Marco13
      Apr 23 '14 at 9:38






    • 2




      @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
      – Stuart Marks
      Apr 25 '14 at 1:45






    • 1




      @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
      – Stuart Marks
      May 29 '15 at 0:11














    • 6




      I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
      – Sotirios Delimanolis
      Apr 22 '14 at 22:40






    • 44




      @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
      – assylias
      Apr 23 '14 at 0:16






    • 2




      A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
      – Marco13
      Apr 23 '14 at 9:38






    • 2




      @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
      – Stuart Marks
      Apr 25 '14 at 1:45






    • 1




      @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
      – Stuart Marks
      May 29 '15 at 0:11








    6




    6




    I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
    – Sotirios Delimanolis
    Apr 22 '14 at 22:40




    I asked for official sources. I don't think it gets more official than this. Give it two days to see all developments.
    – Sotirios Delimanolis
    Apr 22 '14 at 22:40




    44




    44




    @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
    – assylias
    Apr 23 '14 at 0:16




    @StuartMarks "If people think this gives me an unfair advantage etc" => we are here to get answers to questions and this is a perfect answer!
    – assylias
    Apr 23 '14 at 0:16




    2




    2




    A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
    – Marco13
    Apr 23 '14 at 9:38




    A side note: The JVM Spec contains a description that is similar to that of the JLS: docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5 This should be updated as well.
    – Marco13
    Apr 23 '14 at 9:38




    2




    2




    @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
    – Stuart Marks
    Apr 25 '14 at 1:45




    @assylias and Sotirios, thanks for your comments. They, along with the 14 upvotes (as of this writing) on assylias' comment, have alleviated my concerns about any potential unfairness.
    – Stuart Marks
    Apr 25 '14 at 1:45




    1




    1




    @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
    – Stuart Marks
    May 29 '15 at 0:11




    @SotiriosDelimanolis There are a couple bugs that seem relevant, JDK-8043275 and JDK-8043190, and they're marked as fixed in 8u40. However, the behavior seems to be the same. There were also some JVM Spec changes intertwined with this, so perhaps the fix is something other than "restore the old initialization order."
    – Stuart Marks
    May 29 '15 at 0:11













    13














    The interface is not initialized because the constant field InterfaceType.init , which is being initialized by non constant value (method call), is not used anywhere.



    It is known at compile time that constant field of interface is not used anywhere, and the interface is not containing any default method (In java-8) so there is no need to initialize or load the interface.



    Interface will be initialized in following cases,




    • constant field is used in your code.

    • Interface contains a default method (Java 8)


    In case of Default Methods, You are implementing InterfaceType. So, If InterfaceType will contain any default methods, It will be INHERITED (used) in implementing class. And Initialization will be into the picture.



    But, If you are accessing constant field of interface (which is initialized in normal way), The interface initialization is not required.



    Consider following code.



    public class Example {
    public static void main(String args) throws Exception {
    InterfaceType foo = new InterfaceTypeImpl();
    System.out.println(InterfaceType.init);
    foo.method();
    }
    }

    class InterfaceTypeImpl implements InterfaceType {
    @Override
    public void method() {
    System.out.println("implemented method");
    }
    }

    class ClassInitializer {
    static {
    System.out.println("static initializer");
    }
    }

    interface InterfaceType {
    public static final ClassInitializer init = new ClassInitializer();

    public void method();
    }


    In above case, Interface will be initialized and loaded because you are using the field InterfaceType.init.



    I am not giving the default method example as you already given that in your question.



    Java language specification and example is given in JLS 12.4.1 (Example does not contain default methods.)





    I can not find JLS for Default methods, there may be two possibilities




    • Java people forgot to consider the case of default method. (Specification Doc bug.)

    • They just refer the default methods as non-constant member of
      interface. (But mentioned no where, again Specification Doc bug.)






    share|improve this answer























    • I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
      – Sotirios Delimanolis
      Apr 16 '14 at 13:52










    • @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
      – Not a bug
      Apr 16 '14 at 16:38










    • Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
      – Sotirios Delimanolis
      Apr 16 '14 at 16:45










    • I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
      – Not a bug
      Apr 16 '14 at 17:41






    • 1




      @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
      – Lokesh
      Apr 18 '14 at 3:45
















    13














    The interface is not initialized because the constant field InterfaceType.init , which is being initialized by non constant value (method call), is not used anywhere.



    It is known at compile time that constant field of interface is not used anywhere, and the interface is not containing any default method (In java-8) so there is no need to initialize or load the interface.



    Interface will be initialized in following cases,




    • constant field is used in your code.

    • Interface contains a default method (Java 8)


    In case of Default Methods, You are implementing InterfaceType. So, If InterfaceType will contain any default methods, It will be INHERITED (used) in implementing class. And Initialization will be into the picture.



    But, If you are accessing constant field of interface (which is initialized in normal way), The interface initialization is not required.



    Consider following code.



    public class Example {
    public static void main(String args) throws Exception {
    InterfaceType foo = new InterfaceTypeImpl();
    System.out.println(InterfaceType.init);
    foo.method();
    }
    }

    class InterfaceTypeImpl implements InterfaceType {
    @Override
    public void method() {
    System.out.println("implemented method");
    }
    }

    class ClassInitializer {
    static {
    System.out.println("static initializer");
    }
    }

    interface InterfaceType {
    public static final ClassInitializer init = new ClassInitializer();

    public void method();
    }


    In above case, Interface will be initialized and loaded because you are using the field InterfaceType.init.



    I am not giving the default method example as you already given that in your question.



    Java language specification and example is given in JLS 12.4.1 (Example does not contain default methods.)





    I can not find JLS for Default methods, there may be two possibilities




    • Java people forgot to consider the case of default method. (Specification Doc bug.)

    • They just refer the default methods as non-constant member of
      interface. (But mentioned no where, again Specification Doc bug.)






    share|improve this answer























    • I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
      – Sotirios Delimanolis
      Apr 16 '14 at 13:52










    • @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
      – Not a bug
      Apr 16 '14 at 16:38










    • Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
      – Sotirios Delimanolis
      Apr 16 '14 at 16:45










    • I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
      – Not a bug
      Apr 16 '14 at 17:41






    • 1




      @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
      – Lokesh
      Apr 18 '14 at 3:45














    13












    13








    13






    The interface is not initialized because the constant field InterfaceType.init , which is being initialized by non constant value (method call), is not used anywhere.



    It is known at compile time that constant field of interface is not used anywhere, and the interface is not containing any default method (In java-8) so there is no need to initialize or load the interface.



    Interface will be initialized in following cases,




    • constant field is used in your code.

    • Interface contains a default method (Java 8)


    In case of Default Methods, You are implementing InterfaceType. So, If InterfaceType will contain any default methods, It will be INHERITED (used) in implementing class. And Initialization will be into the picture.



    But, If you are accessing constant field of interface (which is initialized in normal way), The interface initialization is not required.



    Consider following code.



    public class Example {
    public static void main(String args) throws Exception {
    InterfaceType foo = new InterfaceTypeImpl();
    System.out.println(InterfaceType.init);
    foo.method();
    }
    }

    class InterfaceTypeImpl implements InterfaceType {
    @Override
    public void method() {
    System.out.println("implemented method");
    }
    }

    class ClassInitializer {
    static {
    System.out.println("static initializer");
    }
    }

    interface InterfaceType {
    public static final ClassInitializer init = new ClassInitializer();

    public void method();
    }


    In above case, Interface will be initialized and loaded because you are using the field InterfaceType.init.



    I am not giving the default method example as you already given that in your question.



    Java language specification and example is given in JLS 12.4.1 (Example does not contain default methods.)





    I can not find JLS for Default methods, there may be two possibilities




    • Java people forgot to consider the case of default method. (Specification Doc bug.)

    • They just refer the default methods as non-constant member of
      interface. (But mentioned no where, again Specification Doc bug.)






    share|improve this answer














    The interface is not initialized because the constant field InterfaceType.init , which is being initialized by non constant value (method call), is not used anywhere.



    It is known at compile time that constant field of interface is not used anywhere, and the interface is not containing any default method (In java-8) so there is no need to initialize or load the interface.



    Interface will be initialized in following cases,




    • constant field is used in your code.

    • Interface contains a default method (Java 8)


    In case of Default Methods, You are implementing InterfaceType. So, If InterfaceType will contain any default methods, It will be INHERITED (used) in implementing class. And Initialization will be into the picture.



    But, If you are accessing constant field of interface (which is initialized in normal way), The interface initialization is not required.



    Consider following code.



    public class Example {
    public static void main(String args) throws Exception {
    InterfaceType foo = new InterfaceTypeImpl();
    System.out.println(InterfaceType.init);
    foo.method();
    }
    }

    class InterfaceTypeImpl implements InterfaceType {
    @Override
    public void method() {
    System.out.println("implemented method");
    }
    }

    class ClassInitializer {
    static {
    System.out.println("static initializer");
    }
    }

    interface InterfaceType {
    public static final ClassInitializer init = new ClassInitializer();

    public void method();
    }


    In above case, Interface will be initialized and loaded because you are using the field InterfaceType.init.



    I am not giving the default method example as you already given that in your question.



    Java language specification and example is given in JLS 12.4.1 (Example does not contain default methods.)





    I can not find JLS for Default methods, there may be two possibilities




    • Java people forgot to consider the case of default method. (Specification Doc bug.)

    • They just refer the default methods as non-constant member of
      interface. (But mentioned no where, again Specification Doc bug.)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Apr 23 '14 at 7:04

























    answered Apr 16 '14 at 6:08









    Not a bug

    3,39312562




    3,39312562












    • I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
      – Sotirios Delimanolis
      Apr 16 '14 at 13:52










    • @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
      – Not a bug
      Apr 16 '14 at 16:38










    • Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
      – Sotirios Delimanolis
      Apr 16 '14 at 16:45










    • I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
      – Not a bug
      Apr 16 '14 at 17:41






    • 1




      @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
      – Lokesh
      Apr 18 '14 at 3:45


















    • I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
      – Sotirios Delimanolis
      Apr 16 '14 at 13:52










    • @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
      – Not a bug
      Apr 16 '14 at 16:38










    • Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
      – Sotirios Delimanolis
      Apr 16 '14 at 16:45










    • I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
      – Not a bug
      Apr 16 '14 at 17:41






    • 1




      @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
      – Lokesh
      Apr 18 '14 at 3:45
















    I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
    – Sotirios Delimanolis
    Apr 16 '14 at 13:52




    I'm looking for a reference for the default method. The field was just to demonstrate that the interface was initialized or not.
    – Sotirios Delimanolis
    Apr 16 '14 at 13:52












    @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
    – Not a bug
    Apr 16 '14 at 16:38




    @SotiriosDelimanolis I mentioned the reason in answer for Default method...but unfortunately any JLS not found for default method yet.
    – Not a bug
    Apr 16 '14 at 16:38












    Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
    – Sotirios Delimanolis
    Apr 16 '14 at 16:45




    Unfortunately, that's what I am looking for. I feel like your answer is just repeating things I've already stated in the question, ie. that an interface will be initialized if it contains a default method and a class that implements the interface is initialized.
    – Sotirios Delimanolis
    Apr 16 '14 at 16:45












    I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
    – Not a bug
    Apr 16 '14 at 17:41




    I think java people forgot to consider the case of default method, Or they just refer the default methods as non-constant member of interface(my assumption, can not find in any doc).
    – Not a bug
    Apr 16 '14 at 17:41




    1




    1




    @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
    – Lokesh
    Apr 18 '14 at 3:45




    @KishanSarsechaGajjar: What do you mean by non constant field in interface? Any variable/field in interface is static final by default.
    – Lokesh
    Apr 18 '14 at 3:45











    10














    The instanceKlass.cpp file from the OpenJDK contains the initialization method InstanceKlass::initialize_impl that corresponds to the Detailed Initialization Procedure in the JLS, which is analogously found in the Initialization section in the JVM Spec.



    It contains a new step that is not mentioned in the JLS and not in the JVM book that is referred to in the code:



    // refer to the JVM book page 47 for description of steps
    ...

    if (this_oop->has_default_methods()) {
    // Step 7.5: initialize any interfaces which have default methods
    for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
    Klass* iface = this_oop->local_interfaces()->at(i);
    InstanceKlass* ik = InstanceKlass::cast(iface);
    if (ik->has_default_methods() && ik->should_be_initialized()) {
    ik->initialize(THREAD);
    ....
    }
    }
    }


    So this initialization has been implemented explicitly as a new Step 7.5. This indicates that this implementation followed some specification, but it seems that the written specification on the website has not been updated accordingly.



    EDIT: As a reference, the commit (from October 2012!) where the respective step has been included in the implementation: http://hg.openjdk.java.net/jdk8/build/hotspot/rev/4735d2c84362



    EDIT2: Coincidentally, I found this Document about default methods in hotspot which contains an interesting side note at the end:




    3.7 Miscellaneous



    Because interfaces now have bytecode in them, we must initialize them at the
    time that an implementing class is initialized.







    share|improve this answer



















    • 1




      Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
      – Stuart Marks
      Apr 25 '14 at 1:47
















    10














    The instanceKlass.cpp file from the OpenJDK contains the initialization method InstanceKlass::initialize_impl that corresponds to the Detailed Initialization Procedure in the JLS, which is analogously found in the Initialization section in the JVM Spec.



    It contains a new step that is not mentioned in the JLS and not in the JVM book that is referred to in the code:



    // refer to the JVM book page 47 for description of steps
    ...

    if (this_oop->has_default_methods()) {
    // Step 7.5: initialize any interfaces which have default methods
    for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
    Klass* iface = this_oop->local_interfaces()->at(i);
    InstanceKlass* ik = InstanceKlass::cast(iface);
    if (ik->has_default_methods() && ik->should_be_initialized()) {
    ik->initialize(THREAD);
    ....
    }
    }
    }


    So this initialization has been implemented explicitly as a new Step 7.5. This indicates that this implementation followed some specification, but it seems that the written specification on the website has not been updated accordingly.



    EDIT: As a reference, the commit (from October 2012!) where the respective step has been included in the implementation: http://hg.openjdk.java.net/jdk8/build/hotspot/rev/4735d2c84362



    EDIT2: Coincidentally, I found this Document about default methods in hotspot which contains an interesting side note at the end:




    3.7 Miscellaneous



    Because interfaces now have bytecode in them, we must initialize them at the
    time that an implementing class is initialized.







    share|improve this answer



















    • 1




      Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
      – Stuart Marks
      Apr 25 '14 at 1:47














    10












    10








    10






    The instanceKlass.cpp file from the OpenJDK contains the initialization method InstanceKlass::initialize_impl that corresponds to the Detailed Initialization Procedure in the JLS, which is analogously found in the Initialization section in the JVM Spec.



    It contains a new step that is not mentioned in the JLS and not in the JVM book that is referred to in the code:



    // refer to the JVM book page 47 for description of steps
    ...

    if (this_oop->has_default_methods()) {
    // Step 7.5: initialize any interfaces which have default methods
    for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
    Klass* iface = this_oop->local_interfaces()->at(i);
    InstanceKlass* ik = InstanceKlass::cast(iface);
    if (ik->has_default_methods() && ik->should_be_initialized()) {
    ik->initialize(THREAD);
    ....
    }
    }
    }


    So this initialization has been implemented explicitly as a new Step 7.5. This indicates that this implementation followed some specification, but it seems that the written specification on the website has not been updated accordingly.



    EDIT: As a reference, the commit (from October 2012!) where the respective step has been included in the implementation: http://hg.openjdk.java.net/jdk8/build/hotspot/rev/4735d2c84362



    EDIT2: Coincidentally, I found this Document about default methods in hotspot which contains an interesting side note at the end:




    3.7 Miscellaneous



    Because interfaces now have bytecode in them, we must initialize them at the
    time that an implementing class is initialized.







    share|improve this answer














    The instanceKlass.cpp file from the OpenJDK contains the initialization method InstanceKlass::initialize_impl that corresponds to the Detailed Initialization Procedure in the JLS, which is analogously found in the Initialization section in the JVM Spec.



    It contains a new step that is not mentioned in the JLS and not in the JVM book that is referred to in the code:



    // refer to the JVM book page 47 for description of steps
    ...

    if (this_oop->has_default_methods()) {
    // Step 7.5: initialize any interfaces which have default methods
    for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
    Klass* iface = this_oop->local_interfaces()->at(i);
    InstanceKlass* ik = InstanceKlass::cast(iface);
    if (ik->has_default_methods() && ik->should_be_initialized()) {
    ik->initialize(THREAD);
    ....
    }
    }
    }


    So this initialization has been implemented explicitly as a new Step 7.5. This indicates that this implementation followed some specification, but it seems that the written specification on the website has not been updated accordingly.



    EDIT: As a reference, the commit (from October 2012!) where the respective step has been included in the implementation: http://hg.openjdk.java.net/jdk8/build/hotspot/rev/4735d2c84362



    EDIT2: Coincidentally, I found this Document about default methods in hotspot which contains an interesting side note at the end:




    3.7 Miscellaneous



    Because interfaces now have bytecode in them, we must initialize them at the
    time that an implementing class is initialized.








    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited May 4 '14 at 11:28

























    answered Apr 23 '14 at 9:31









    Marco13

    41.8k854107




    41.8k854107








    • 1




      Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
      – Stuart Marks
      Apr 25 '14 at 1:47














    • 1




      Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
      – Stuart Marks
      Apr 25 '14 at 1:47








    1




    1




    Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
    – Stuart Marks
    Apr 25 '14 at 1:47




    Thanks for digging this up. (+1) It may be that the new "step 7.5" was inadvertently omitted from the spec, or that it was proposed and rejected and the implementation never was fixed up to remove it.
    – Stuart Marks
    Apr 25 '14 at 1:47











    1














    I'll try to make a case that an interface initialization should not cause any side-channel side effects that the subtypes depend on, therefore, whether this is a bug or not, or whichever way the Java fixes it, it should not matter to the application in which order interfaces are initialized.



    In the case of a class, it is well accepted that it can cause side effects that subclasses depend on. For example



    class Foo{
    static{
    Bank.deposit($1000);
    ...


    Any subclass of Foo would expect that they'll see $1000 in the bank, anywhere in the subclass code. Therefore the superclass is initialized prior to the subclass.



    Shouldn't we do the same thing for superintefaces as well? Unfortunately, the order of superinterfaces are not supposed to be significant, therefore there is no well defined order in which to initialize them.



    So we better not establish this kind of side effects in interface initializations. After all, interface is not meant for these features (static fields/methods) we pile on for convenience.



    Therefore if we follow that principle, it'll be no concern to us in which order interfaces are initialized.






    share|improve this answer


























      1














      I'll try to make a case that an interface initialization should not cause any side-channel side effects that the subtypes depend on, therefore, whether this is a bug or not, or whichever way the Java fixes it, it should not matter to the application in which order interfaces are initialized.



      In the case of a class, it is well accepted that it can cause side effects that subclasses depend on. For example



      class Foo{
      static{
      Bank.deposit($1000);
      ...


      Any subclass of Foo would expect that they'll see $1000 in the bank, anywhere in the subclass code. Therefore the superclass is initialized prior to the subclass.



      Shouldn't we do the same thing for superintefaces as well? Unfortunately, the order of superinterfaces are not supposed to be significant, therefore there is no well defined order in which to initialize them.



      So we better not establish this kind of side effects in interface initializations. After all, interface is not meant for these features (static fields/methods) we pile on for convenience.



      Therefore if we follow that principle, it'll be no concern to us in which order interfaces are initialized.






      share|improve this answer
























        1












        1








        1






        I'll try to make a case that an interface initialization should not cause any side-channel side effects that the subtypes depend on, therefore, whether this is a bug or not, or whichever way the Java fixes it, it should not matter to the application in which order interfaces are initialized.



        In the case of a class, it is well accepted that it can cause side effects that subclasses depend on. For example



        class Foo{
        static{
        Bank.deposit($1000);
        ...


        Any subclass of Foo would expect that they'll see $1000 in the bank, anywhere in the subclass code. Therefore the superclass is initialized prior to the subclass.



        Shouldn't we do the same thing for superintefaces as well? Unfortunately, the order of superinterfaces are not supposed to be significant, therefore there is no well defined order in which to initialize them.



        So we better not establish this kind of side effects in interface initializations. After all, interface is not meant for these features (static fields/methods) we pile on for convenience.



        Therefore if we follow that principle, it'll be no concern to us in which order interfaces are initialized.






        share|improve this answer












        I'll try to make a case that an interface initialization should not cause any side-channel side effects that the subtypes depend on, therefore, whether this is a bug or not, or whichever way the Java fixes it, it should not matter to the application in which order interfaces are initialized.



        In the case of a class, it is well accepted that it can cause side effects that subclasses depend on. For example



        class Foo{
        static{
        Bank.deposit($1000);
        ...


        Any subclass of Foo would expect that they'll see $1000 in the bank, anywhere in the subclass code. Therefore the superclass is initialized prior to the subclass.



        Shouldn't we do the same thing for superintefaces as well? Unfortunately, the order of superinterfaces are not supposed to be significant, therefore there is no well defined order in which to initialize them.



        So we better not establish this kind of side effects in interface initializations. After all, interface is not meant for these features (static fields/methods) we pile on for convenience.



        Therefore if we follow that principle, it'll be no concern to us in which order interfaces are initialized.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Apr 22 '14 at 22:38









        ZhongYu

        15.3k31845




        15.3k31845






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f23096084%2fwhen-is-an-interface-with-a-default-method-initialized%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Sphinx de Gizeh

            Dijon

            Équipe cycliste