4

I have the following code:

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

class A {
    static {
        System.out.println("A static initializer block");
    }
    static void methodOfA() {
        System.out.println("A static method");
    }
    {
        System.out.println("A non-static initializer block");
    }
    public A() {
        System.out.println("A constructor");
    }
    public A(String a) {
        System.out.println(a);
    }
}

class B extends A {
    static {
        System.out.println("B static initializer block");
    }
    static void methodOfB() {
        System.out.println("B static method");
    }
    {
        System.out.println("B non-static initializer block");
    }
    public B() {
        super("test");
        System.out.println("B constructor");
    }
}

The output I get is:

A static initializer block
B static initializer block
A non-static initializer block
test
B non-static initializer block
B constructor

But I would expect it to be:

A static initializer block
B static initializer block
A non-static initializer block
B non-static initializer block
test
B constructor

Because, as far as I know, initializer blocks are loaded before the constructor.

I have been browsing google and stackoverflow for an answer but have been unsuccesful.

Any clarification would be much appreciated!

koenek
  • 61
  • 2
  • 1
    Does this answer your question? [Behavior of static blocks with inheritance](https://stackoverflow.com/questions/10698516/behavior-of-static-blocks-with-inheritance) – andreoss Jul 10 '20 at 12:02
  • As `A` must be fully initialized before `B` it is reasonable to assume that the `A` constructor is called before `B`s initializer. – Smutje Jul 10 '20 at 12:04
  • @andreoss Thanks, but unfortunatel that doesn't answer my question because that question is specifically on how static initializerblocks work. Thanks for the suggestion though! – koenek Jul 10 '20 at 12:20

2 Answers2

3

The superclass constructor executes before the subclass constructor and a non-static initializer is executed immediately before the constructor is. Hence, in your output, "test" appears before "B non-static initializer block".

Abra
  • 19,142
  • 7
  • 29
  • 41
2

static initializer blocks are only executed once when a class is initialized by the JVM whereas instance initializer blocks are executed every time an instance of a class is created. Instance initializer blocks execute before the code in the constructor but after the call to parent's class constructor (i.e. after super() call).

Java compiler copies the code of instance initializer blocks in to every constructor. Instance initializer block code is placed after the super() call. So following code:

{
    System.out.println("B non-static initializer block");
}

public B() {
    super("test");
    System.out.println("B constructor");
}

will be transformed in to:

public B() {
    super("test");
    System.out.println("B non-static initializer block");
    System.out.println("B constructor");
}

This explains why test is printed on the console before instance initializer block of the B class executes.

Yousaf
  • 27,861
  • 6
  • 44
  • 69
  • Nothing is copied into constructor at the JVM level.. also, instance blocks are executed before the constructor; moreover, even statically bound (initialized in the code) instance variables are executed before the constructor's body. – Giorgi Tsiklauri Jul 10 '20 at 14:04
  • @GiorgiTsiklauri _The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors_ - this quote if from [java docs](https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html) – Yousaf Jul 10 '20 at 14:19
  • @GiorgiTsiklauri _also, instance blocks are executed before the constructor;_ - i think that is what i said in my answer. Code in the instance initializer block is executed before the code in the constructor. Only exception is the call to `super()` which executes before the instance initializer block. – Yousaf Jul 10 '20 at 14:27
  • That seems right. I accidentally read your code in the opposite order. – Giorgi Tsiklauri Jul 10 '20 at 15:07