3

I knew that when i create an instance static block first initialized then code block and then constructor here my code

public class Main{

public Main() {
    out.println("constructor initialised");
}

static {
    out.println("static block initialised");
}
{
    out.println("Code block initialised");
}

public static void main(String... args) {

    new Main();
}

}

output like this

static block initialised
Code block initialised
constructor initialised

the output above clear my concept but when I extend some class like this

public class Main extends Bear{

public Main() {
    out.println("constructor initialised");
}

static {
    out.println("static block initialised");
}
{
    out.println("Code block initialised");
}

public static void main(String... args) {
    new Main();
}
}

Bear Class

class Bear{
static {
    out.println("static block initialised of bear class");
}

{
    System.out.println("Code bLock initialised of bear class");
}

void run() {
    out.println("running...");
}
}

output like this:

static block initialised of bear class
static block initialised
Code bLock initialised of bear class
Code block initialised
constructor initialised

when extending class the order of execution is changed i don't understand why this was happens the output above

Partho
  • 2,153
  • 3
  • 17
  • 27

1 Answers1

5

I believe the way these work is:

  • static blocks are called when a class is first loaded (basically the first time you use a class in your project) and so these happen first
  • initialized (code) blocks are essentially copied in to each constructor at the start (after the call to super()) so you can share code (not great style though)
  • constructors are well... Constructors...

The reason they appear in this order is because the child class depends on the parent class existing. The child class can not be loaded before the parent, and so the static initializor for the parent is called to load it, and then the child class is loaded in after that.

Once each class is loaded, it will then call the constructors (including the non-static code blocks) to initialise your objects. Again, the child class depends on the parent existing and being properly setup, so the base class constructor is called first and then it calls the derived class constructor. It needs to be done in this order so that the child class can depend on certain parameters of the parent. If you added in an explicit constructor to your base class, you'd get output something like the below:

Class is loaded

  • static block initialised of bear class
  • static block initialised

Base class constructor

  • Code bLock initialised of bear class
  • Constructor initialised of bear class

Child class constructor

  • Code block initialised
  • constructor initialised

If you called new Main() twice, you'd see the above output the first time but then the static blocks would probably be missing the second time, as the class would already be loaded.

Will Moffat
  • 169
  • 8
  • 3
    Worth noting that initialiser blocks are copied into the constructor AFTER THE CALL TO SUPER. This is important as it is why Bear’s initialiser block happens first (Main implicitly calls super to Bear. Bear implicitly calls super to Ovject, and then runs initialiser, then we’re back in Main (after the implicit super call) and so run it’s initialiser block, and then back to the rest of Main’s constructor). – BeUndead Jun 26 '21 at 03:03
  • 1
    Yeah that's an excellent point. I appreciate I could've made this clearer. Updated to mention that it's called after super – Will Moffat Jun 26 '21 at 03:08