srnjak srnjak - 1 month ago 5x
Java Question

Strange Java behaviour with static and final qualifiers

In our team we found strange behaviour where we used both

qualifiers. This is our test class:

public class Test {

public static final Test me = new Test();
public static final Integer I = 4;
public static final String S = "abc";

public Test() {

public static Test getInstance() { return me; }

public static void main(String[] args) {

When we run the
method, we get a result of:


I would understand, that it would write
values in both times, since code of static class members is executed from top to bottom.

Can anyone explain, why this behaviour is happening?


These are the steps taken when you run your program:

  1. Before main can be run, the Test class must be initialized by running static initializers in order of appearance.
  2. To initialize the me field, start executing new Test().
  3. Print the value of I. Since the field type is Integer, what seems like a compile-time constant 4 becomes a computed value (Integer.valueOf(4)). The initializer of this field has not yet run, printing the initial value null.
  4. Print the value of S. Since it is initialized with a compile-time constant, this value is baked into the referencing site, printing abc.
  5. new Test() completes, now the initializer for I executes.

Lesson: if you rely on eagerly initialized static singletons, place the singleton declaration as the last static field declaration, or resort to a static initializer block that occurs after all other static declarations. That will make the class appear fully initialized to the singleton's construction code.