ProgrammingMiddle/Senior Java Developer

What is class initialization order in Java, how does it work, and what can lead to misunderstanding the order of initialization of static and non-static members?

Pass interviews with Hintsage AI assistant

Answer.

The class initialization order in Java defines the sequence in which fields, blocks, and constructors are initialized. In brief:

  1. Static fields and static initializers are executed in the order they appear in the class when the class is loaded by the JVM (once per class).
  2. Non-static fields and initializers are executed in the order they appear EACH time an instance is created, before the constructor is called.
  3. Constructor is executed after the initialization of all fields and blocks.

Example

class Parent { static { System.out.println("Parent static"); } { System.out.println("Parent init"); } Parent() { System.out.println("Parent constructor"); } } class Child extends Parent { static { System.out.println("Child static"); } { System.out.println("Child init"); } Child() { System.out.println("Child constructor"); } } // new Child() -> what order?

The output will be:

  1. Parent static
  2. Child static
  3. Parent init
  4. Parent constructor
  5. Child init
  6. Child constructor

First, the static blocks of parents, then the static blocks of children, followed by the non-static blocks and constructors in the order of inheritance.

Trick Question.

Question: When will the static initializers in the class be executed:

class Ex {
    static { System.out.println("static"); }
}

— upon creating the first instance or the first use of any static method/field?

Answer: The static initializer is executed at the first access to the class, including access to any static member (method/field), not just when creating an instance.

Examples of real errors due to lack of knowledge of the nuances of the topic.


Story

In a banking application, a static connection pool was initialized in a static block, but due to accessing a static method before creating the first instance, the connection was not created yet. This led to a NullPointerException under load.


Story

The logging service depended on a non-static field that was initialized after the parent class constructor was called. Logs were written to a null logger, causing important error messages to be lost.


Story

When adding a new field with an initial value, the developer placed it after the initialization block: the block tried to use an uninitialized field, resulting in errors during application startup and a difficult search for the cause.