Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static field initialization sequence in a class

Tags:

java

static

I'm having trouble understanding initialization order when a class has a static instance of itself. Also, why this behavior seems to be different for a String.

Please see the following example:

public class StaticCheck {
    private static StaticCheck INSTANCE = new StaticCheck();    

    private static final List<String> list =
        new ArrayList<String>(Arrays.asList("hello"));
    private static final Map<String, String> map =
        new HashMap<String, String>();  
    private static final  String name = "hello";

    public static StaticCheck getInstance() {
        return INSTANCE;
    }

    private StaticCheck() {
        load();     
    }

    private void load() {
        if(list != null) {
            System.out.println("list is nonnull");
        } else {
            System.out.println("List is null");
        }
        if(name != null) {
            System.out.println("name is nonnull");
        } else {
            System.out.println("name is null");
        }
        if(map != null) {
            System.out.println("Map is nonnull");
        } else {
            System.out.println("Map is null");
        }
    }

    public static void main(String[] args) {
        StaticCheck check = StaticCheck.getInstance();
    }
}

Output:

List is null
name is nonnull
Map is null

I am absolutely not clear on why the field name is not null. Static fields are initialized in the following cases as mentioned under Class initialization: http://javarevisited.blogspot.in/2012/07/when-class-loading-initialization-java-example.html

Looking into the above example, my thoughts:

  1. As said, static fields are initialized before instance initialization in Java. Here, when I am invoking the static method getInstance(), it will lead to class initialization which implies initialization of static fields. In this case, the fields map and and list shouldn't be null.

  2. In the above example, since the field INSTANCE is static, its object initialization takes place and its constructor calls load() when other fields were not initialized. Because of this the fields list and map are null. So then why did name get initialized? I am a little confused.

like image 201
Xephonia Avatar asked Apr 13 '15 17:04

Xephonia


1 Answers

The String type name variable is a compile time constant, which are inlined by the compiler at compile time. So, the condition:

if (name != null)

after compilation will become:

if ("hello" != null)

which is of course true.

As for why map and list are null, that's because, when the class is initialized, INSTANCE field is initialized, calling the constructor, which in turn calls the load() method. Note that, by this time, the other static initializers has not yet been run. So, map and list are still null. So, printing them in load() method will be null.

like image 59
Rohit Jain Avatar answered Oct 20 '22 06:10

Rohit Jain