Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 909
ALBI Avatar asked Dec 25 '22 16:12

ALBI


1 Answers

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.

like image 142
Jon Skeet Avatar answered Dec 28 '22 07:12

Jon Skeet