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.
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.