Search code examples
javanullpointerexceptionstatic-variables

Static Initialization in Java?


I was trying to execute the following code:

public class StaticTest {

    private static List<String> dat1;
    {
        dat1 = new ArrayList<>(); 
    }

    private StaticTest(){
        System.out.println(dat1.contains("a")); //Marked Line 2: this one is not throwing
    }

    public static void main(String[] args) {
        System.out.println(dat1.contains("a")); //Marked Line 1: This line throws null pointer 
        new StaticTest(); 
    }
}

I tried to execute the above code, I got Null pointer exception at Marked Line 1. But when I commented Marked Line 1 I got the output.

Why am I getting the exception in first case and not in second ?

When I use private static List<String> dat1= new ArrayList<>();, no exception is thrown.


Solution

  • Simple:

    System.out.println(dat1.contains("a")); 
    

    runs a constructor (because it is inside the constructor!). And part of running the constructor is: to run all non-static initializer blocks of a class.

    Whereas:

    public static void main(String[] args) {
      System.out.println(dat1.contains("a")); //Marked Line 1: This line 
    

    does only run your static initializers - but no constructor code (it does - but after that line).

    So your problem is that this initializer block:

    {
        dat1 = new ArrayList<>(); 
    }
    

    isn't static!

    In other words: your problem is caused by mixing static/non-static in very unhealthy ways. If a field is static, make sure that a static init code will initialize it.

    Btw: the reasonable solution is to simply do:

    private final static List<String> data = new ArrayList<>();
    

    This makes sure that the list is initialized as soon as possible; and then compiler will even tell you when you forgot to initialize it.