1
package test;

import java.util.HashMap;

class Check {
    private static Check check = new Check(); 
    private static HashMap<String,String> map = new HashMap<String, String>();
    static{
        System.out.println("***********In static block***********");
        Check.map.put("1", "One");
        Check.map.put("2","Two");
    }
    private Check(){
        System.out.println("Map Contains "+map.get("1"));
    }

    public static Check getCheck() {
        return Check.check;
    }

}
public class CheckStatic{
    public static void main(String[] args) {
        Check.getCheck();
    }
}

I have created Singleton class which has static block. And in static block I have initialized hashmap and trying to access that in constructor of Singletion class.But I am getting exceptionInInitializerError. Please suggest what is am trying which is wrong...

jruizaranguren
  • 12,679
  • 7
  • 55
  • 73
  • 1
    If you want this to be a singleton, why don't you initialize the Map in your constructor of the singleton? Your problem is actually in your constructor since this accesses the map and is first called in static code to initialize your singleton. Doing initialization in your constructor will prevent those problems – Matthias Aug 22 '13 at 09:34
  • @Matthias +1 and while on the subject, why make the map static in the first place. It should be a `private final` instance variable. But, since this may be just an excerpt of the total program, better not guess too far. – Marko Topolnik Aug 22 '13 at 09:48
  • Also consider initialising the Map using an initialiser, eg: `new HashMap() {{` `put("1", "One");` `put("2", "Two");` `}}` – Yusuf Jakoet Aug 22 '13 at 10:02

6 Answers6

2

Here is the problem:

private static Check check = new Check(); 

and in the constructor you have

System.out.println("Map Contains "+map.get("1"));

So you've got a Catch-22 situation: you want the map to exist before the constructor has run, and you want the constructor to run before initializing the map.

All you need to do is put the declaration of the check singleton below the static initializer which sets up the map. At that point the constructor will be safe to run.

As a side note, make that check variable final. That's standard for singletons, and for a good reason: it guarantees that there will be only one instance.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
1

The line private static Check check = new Check(); runs the constructor which requires map (map.get(1)) whereas map is not yet created.

You may try to assign check at the end of your static block, when you are sure mapexists.

I hope it helps.

private static Check check; 
private static HashMap<String,String> map = new HashMap<String, String>();
static{
    System.out.println("***********In static block***********");
    Check.map.put("1", "One");
    Check.map.put("2","Two");
    check = new Check(); // Now, maps exists, the ctr can use it.
}
johan d
  • 2,798
  • 18
  • 26
0

You call the constructor, which uses the map, before the map is created and initialized. Initialize check after the map in the static block.

class Check {
    private static Check check; 
    private static HashMap<String,String> map = new HashMap<String, String>();
    static{
        System.out.println("***********In static block***********");
        Check.map.put("1", "One");
        Check.map.put("2","Two");

        check = new Check();
    }
    private Check(){
        System.out.println("Map Contains "+map.get("1"));
    }

    public static Check getCheck() {
        return Check.check;
    }

}
WilQu
  • 7,131
  • 6
  • 30
  • 38
0

Your map contains null value. You are trying to get map.get("1") the value from null. So only you got exceptionInInitializerError this Exception.

private static HashMap<String,String> map = new HashMap<String, String>();
private static Check check = new Check();

instead of

private static Check check = new Check();
private static HashMap<String,String> map = new HashMap<String, String>();
newuser
  • 8,338
  • 2
  • 25
  • 33
0

Your singleton instance of Check is created before map - therefore the latter is still null when check's constructor is executed.

To fix that, just flip the order of the two static variables.

class Check {
    private static HashMap<String,String> map = new HashMap<String, String>();
    private static Check check = new Check(); 

See also this question and answer: Java : in what order are static final fields initialized?

Community
  • 1
  • 1
Thomas
  • 17,016
  • 4
  • 46
  • 70
0

The class is initialized in the order of the declarations. In your case this means:

private static Check check = new Check();

Is executed before:

private static HashMap<String,String> map = new HashMap<String, String>();

And therefore you get the error in the constructor because map has not been initialized.

Re-structure your class like this:

class Check 
{
  private static HashMap<String,String> map = new HashMap<String, String>();
  static
  {
    System.out.println("***********In static block***********");
    Check.map.put("1", "One");
    Check.map.put("2","Two");
  }

  private static Check check = new Check(); 

  private Check()
  {
    System.out.println("Map Contains "+map.get("1"));
  }

  ...
}
Nick Holt
  • 33,455
  • 4
  • 52
  • 58