1

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.

0

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. I missed the "static" keyword before the block. I tested and it works as expected.
1

This code

{
    dat1 = new ArrayList<>(); 
}

This constructor block. Which will be executed every constructor after super() , so it will not run on Mark1 yet.

If you have code like this, it will be executed when class is loaded.

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

more detail here http://www.jusfortechies.com/java/core-java/static-blocks.php

1 Comment

It's an initializer block.
1

Hi @kajal please refer to the correct code below:-

 public class StaticTest {

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

    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(); 
    }
}

Instance block is executes when you create a instance of that class. Question why you are getting the NullPointerException :- Please find the below flow of the StaticTest class execution :-

  1. First all the import class will load like :-
    1. Object class 2.java.lang Package Class 3.java.util.ArrayList Class.
  2. The compiler goes through the StaticTest Class and allocate the Memory for the all the Static Members in your case it is dat1.
  3. Now the javac compiler searches for the Static block for the execution. in your case their is no Static block.
  4. Now the compiler executes the main method and executes the System.out.println(dat1.contains("a")); is called as null.contains("a"); which trhows the execption but as i said the Instance block is executes when you create a instance of that class. so dat1 is initialized when you create object new StaticTest();

2 Comments

Thanks Husnain. I tested the code and it works fine.
Hi @kajal, can you please vote up and accept my answer.
0

Your code:

{
    dat1 = new ArrayList<>(); 
}

Is a non-static initializer. This is called, when you are calling the constructor with: new StaticTest(). After that dat1 will be initialized.

You can change your code to static initializing by preceding it with the static keyword:

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

Then it will work for both cases.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.