0

I ran across this code:

public class A {
    static{
        System.out.print("A");
    }

    A(){
        System.out.print("a");
    }
}

public class B extends A {
    static{
        System.out.print("B");
    }

    B(){
        System.out.print("b");
    }
}

public class Test {
    public static void main(String[] args) {
        new B();
    }
}

My understanding of order of object construction is:

  1. Initialize member fields of the base class(es)
  2. Run the base class(es) constructor(s)
  3. Initialize member fields of sub class
  4. Run the constructor of sub class

And my understanding of execution of static initializer is

  • the static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field.

But I can not come up with the correct printing, i got:

A(base initialzer)
a(base constructor)
B(subclass initialize)
b(subclass constructor)

Could someone explain what is the correct order and why?

Update

user1559625
  • 2,583
  • 5
  • 37
  • 75
  • Don't use code formatting for text that isn't code, and do use it for text that is code, or computer output. – user207421 Dec 01 '15 at 07:39
  • Please revisit your code for possible duplicate classes or such. I tested the same and got below output A (base initialize) B (subclass initialize) a (base constructor) b (subclass constructor) – vvs Dec 01 '15 at 08:13
  • @Vinod Madyalkar Hi, Vinod, where is a good place to ask question like this, that I may know part of the picture but still missing something. Afterall, sometimes I may not see the answer even it's right in front of me. – user1559625 Dec 01 '15 at 08:18
  • @user1559625 - This is a good question and SO is the right place to ask these kind of questions. Did you go through answers [here](http://stackoverflow.com/questions/2007666/in-what-order-do-static-initializer-blocks-in-java-run)? – TheLostMind Dec 01 '15 at 08:21
  • @I did. Actually if you see my post, i copied what i learned from your LINK directly into my post as part of my question. But my understanding of "the class B is first accessed" is during creating of B instance, unlike what AntJavaDev write in his answer(is during class load via B extends A). – user1559625 Dec 01 '15 at 08:35
  • yes , because when you request an object with the new keyword , the classloader will first try to load the class if its not already loaded. so in order to get you a B object , it requires the class A to be also loaded – AntJavaDev Dec 01 '15 at 08:51
  • @AntJavaDev Thanks. The explanation is quite clear. But regarding the class loading and class initializing you and Vinod were talking about, if loading and initializing are 2 different steps, then "B extend A" will trigger which (?) which will then trigger the static block being called? – user1559625 Dec 01 '15 at 08:58
  • @Vinod Madyalkar Also please look at the 5 steps listed in http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5. From there I can not seem to see the triggering of running static block via "B extends A", but just a standard "super() -> initializer -> constructor()" process. – user1559625 Dec 01 '15 at 09:12
  • @user1559625 - Class `A` has to be loaded and initialized before class `B` is completely loaded an initialized. So creating an instance of class `B` will involve (first) executing initializers of class `A` (the parent) – TheLostMind Dec 01 '15 at 09:24
  • I get `ABab` as output which is as expected – TheLostMind Dec 01 '15 at 09:25
  • @Vinod Madyalkar If LOADING and INITIALIZING class A are before class B, then how do u get B printed before a. Then what AntJavaDev explained make no sense at all – user1559625 Dec 01 '15 at 09:51
  • 1
    @user1559625 - The static initializers are part of class initialization, which happens after class loading. The following things happen when you create instance of class B. Class B's loading starts, jvm realizes that class B is dependent on class A, So, class A is loaded and initialized. Next class B is initialized. Next constructor of class B is invoked which invokes class A's constructor and then when A's constructor returns, B's constructor is executed – TheLostMind Dec 01 '15 at 09:57
  • 1
    @Vinod Madyalkar class initialzaion where static init take place vs class instance initiation. I see where my confusion was. Thanks Vinod. – user1559625 Dec 01 '15 at 10:23

1 Answers1

2

static blocks will called whenever the class is loaded by the classloader , thus the correct order is :

i) class A is loaded (because B extends A is requested) so the first static block is called , and it prints A

ii)class B is getting loaded , so the second static block gets called , and it prints B

iii)default constructor of A (because new B is requested) so it prints a

iv) and finally default constructor of B as it was requested with new B() so it prints b , the output is ABab

AntJavaDev
  • 1,204
  • 1
  • 18
  • 24
  • *whenever the class is loaded* - Whenever the class is *initialized*. Class loading and initialization are 2 different steps :) – TheLostMind Dec 01 '15 at 08:23