Search code examples
javaabstract-classstatic-block

Behavior of static blocks with Abstract classes


Child Class:

public class ChildExtending extends ParentAbstract{

    public int childInt =111213;
    static{
        System.out.println("child static block executed");
    }

    public ChildExtending() {
        System.out.println("child const initialized");
    }
    public void MethodInChild(){
        System.out.println("MethodInChild called");
    }
    public static void main(String[] args){
        System.out.println(ParentAbstract.parentInt);
        System.out.println(ChildExtending.parentInt);
    }
}

Abstract Class:

public abstract class ParentAbstract {
    public static int parentInt=80713; 
    static{
        System.out.println("parent static executed");
        parentInt=9;
    }

    public ParentAbstract(){
        System.out.println("parentAbstract initialized");
    }

    public void MethodInParent(){
        System.out.println("MethodInParent called");
    }

}

Main class:

public class MainForCheck {
    public static void main(String[] args){
    /*  ParentAbstract pa = new ParentAbstract(){

        };*/

    /*  ChildExtending ce = new ChildExtending();
        ce.childInt=5;*/

        /*ChildExtending ce = new ChildExtending();
        ce.childInt=5;
        ce.MethodInChild();
        System.out.println("pareny int is"+ce.parentInt);*/


        ChildExtending ce = new ChildExtending();
        ce.MethodInParent();

    }
}

This gives me output:

parent static executed ]

child static block executed

parentAbstract initialized

child const initialized

MethodInParent called

Why is it not like this?

parent static executed

parentAbstract initialized

child static block executed

child const initialized

MethodInParent called


Solution

  • Well first ChildExtending needs to be initialized (as a type). That will produce the output of

     parent static executed
     child static block executed
    

    as per section 12.4.2 of the JLS.

    Only once the type is initialized can the constructor be called, at which point you'll get the output of:

     parentAbstract initialized
     child const initialized
    

    And once the object is constructed, you can call an instance method on it, with output of:

    MethodInParent called
    

    I think the piece you're missing is that the type has to be completely initialized before the constructor starts. The constructor call can't initialize just enough of the superclass to call its constructor, then initialize the subclass. Aside from anything else, if you call getClass() in the superclass constructor, that has to be a fully initialized class - which has to be the subclass, because that's what the object is an instance of.