It is common for a class to have constant values defined as class fields (static and final) and then used in instances fields like in code bellow:

We all know that static fields are initialized first and then the instance ones, so it is no surprise until now. To be even more clear, I updated the code by adding code blocks with print statements:

that displays:

It is what we all expected so why I bother with posting about such simple things? It is because Elvis lives again. I get into trouble if I add a singleton instance at the beginning of the class:

The only difference is that we are using that singleton instance so I would expect the same result but instead I get:

In order to understand what happens we need to read When Initialization Occurs:

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.

and Detailed Initialization Procedure, step 3:

For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. The procedure for initializing C is then as follows:

  1. Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.
  2. If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.
  3. If the Class object for C indicates that initialization is in progress for C by the current thread, then this must be a recursive request for initialization. Release LC and complete normally.

After reading above sections, my understanding is that the following happens:

  1. RecursiveInitialization class is initialized because its main method is called.
  2. TROUBLE is a static field so it is initialized.
  3. TROUBLE is an instance of RecursiveInitialization so RecursiveInitialization should be initialized. There is already a class initialization in progress, so it completes normally. Instance field done is initialized with unboxed value of DONE, which is null and we receive that NullPointerException.

A simple fix is to move the singleton declaration and instantion after the static block:

and everything gets back to normal:

If this subjects interests you and you need more information about it, here is another example.

After seeing what can happen if I don’t pay attention to initialization details, I will be more careful in such situations.

Your thoughts are welcome

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Help me to improve your experience on this site!

Rate your overall experience:
How was your experience in few words? What did you expect, what you actually found?
Type above words: