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

我创建了具有静态块的 Singleton 类。在静态块中,我已经初始化了 hashmap 并尝试在 Singletion 类的构造函数中访问它。但是我得到了 exceptionInInitializerError。请建议正在尝试什么是错误的......

4

6 回答 6

2

这是问题所在:

private static Check check = new Check(); 

在你的构造函数中

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

因此,您遇到了 Catch-22 情况:您希望地图在构造函数运行之前存在,并且您希望构造函数在初始化地图之前运行。

您需要做的就是将check单例的声明放在设置地图的静态初始化程序下方。那时,构造函数将可以安全运行。

作为旁注,使该check变量final。这是单例的标准,并且有充分的理由:它保证只有一个实例。

于 2013-08-22T09:32:48.563 回答
1

该行private static Check check = new Check();运行需要map( map.get(1)) 的构造函数,而 map 尚未创建。

当您确定存在时,您可以尝试check在静态块的末尾进行分配。map

我希望它有所帮助。

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.
}
于 2013-08-22T09:33:24.217 回答
0

在创建和初始化地图之前调用使用地图的构造函数。在静态块中初始化check之后。map

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

}
于 2013-08-22T09:33:14.517 回答
0

您的地图包含null价值。您正在尝试map.get("1")从 null 中获取值。所以只有你得到了exceptionInInitializerError这个例外。

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

代替

private static Check check = new Check();
private static HashMap<String,String> map = new HashMap<String, String>();
于 2013-08-22T09:33:34.053 回答
0

您的单例实例Check是之前创建map的 - 因此后者仍然是在执行构造函数null时。check

要解决这个问题,只需翻转两个静态变量的顺序。

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

另请参阅此问题和答案:Java:静态最终字段的初始化顺序是什么?

于 2013-08-22T09:35:30.187 回答
0

该类按照声明的顺序进行初始化。在您的情况下,这意味着:

private static Check check = new Check();

在之前执行:

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

因此,您在构造函数中得到错误,因为map尚未初始化。

像这样重组你的类:

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

  ...
}
于 2013-08-22T09:36:21.437 回答