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 クラスを作成しました。そして、静的ブロックでハッシュマップを初期化し、Singletion クラスのコンストラクターでそれにアクセスしようとしましたが、例外InInitializerError を取得しています。何が間違っているのかを提案してください...

4

6 に答える 6

2

問題は次のとおりです。

private static Check check = new Check(); 

そしてあなたが持っているコンストラクターで

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

したがって、キャッチ 22 の状況があります。コンストラクターが実行される前にマップが存在するようにし、マップを初期化する前にコンストラクターを実行する必要があります。

必要なのはcheck、マップを設定する静的イニシャライザの下にシングルトンの宣言を配置することだけです。その時点で、コンストラクターは安全に実行できます。

補足として、そのcheckvariableを作成しますfinal。これはシングルトンの標準であり、正当な理由があります。これにより、インスタンスが 1 つだけになることが保証されます。

于 2013-08-22T09:32:48.563 に答える
1

行は( )private static Check check = new Check();を必要とするコンストラクターを実行しますが、マップはまだ作成されていません。mapmap.get(1)

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

のシングルトン インスタンスCheckは前に作成されます。mapしたがって、後者はまだのコンストラクタが実行されるnullときです。check

これを修正するには、2 つの静的変数の順序を反転するだけです。

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

この質問と回答も参照してください: Java : static final フィールドはどのような順序で初期化されますか?

于 2013-08-22T09:35:30.187 に答える
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

クラスは宣言順に初期化されます。あなたの場合、これは次のことを意味します:

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 に答える