How are object dependencies between static blocks resolved?

The mechanism is described in detail here, but the five most important points are:

  1. Before a class is referenced, it needs to be initialised.
  2. If initialisation of a class has already begun (or if it’s finished), it isn’t attempted again.
  3. Before a class is initialised, all its superclasses and superinterfaces need to be initialised first.
  4. Static initialisers within a single class are executed in textual order.
  5. Implemented interfaces are initialised in the order in which they appear in the implements clause.

These rules completely define the order in which static blocks are executed.

Your case is rather simple: before you access B.dependsOnA, B needs to be initialised (rule 1), the static initialiser is then trying to access A.list, which triggers the initialisation of class A (again rule 1).

Note that there’s nothing stopping you from creating circular dependencies this way, which will cause interesting things to happen:

public class Bar {
    public static int X = Foo.X+1;

    public static void main(String[] args) {
        System.out.println( Bar.X+" "+Foo.X); // 
    }

}

class Foo {
    public static int X = Bar.X+1;
}

The result here is 2 1 because the way the initialisation happens is this:

  1. Bars initialisation begins.
  2. Bar.Xs initial value is evaluated, which requires initialising Foo first
  3. Foos initialisation begins.
  4. Foo.Xs initial value is evaluated, but since Bars initialisation is already in progress, it isn’t initialised again, Bar.Xs “current” value is used, which is 0, thus Foo.X is initialised to 1.
  5. We’re back to evaluating Bar.Xs value, Foo.X is 1 so Bar.X becomes 2.

This works even if both fields were declared final.

The moral of the story is to be careful with static initialisers referring to other classes in the same library or application (referring to classes in a third party library or standard class library is safe as they won’t be referring back to your class).

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)