2

次のコードでエラーが発生する理由をお聞きしたいと思います。

class A
{
    A()
    {
       statObj.x = 5; 
    }

    int x;
    static A statObj = new A();
}

ExceptionInInitializerError が発生します。理由がわかりません。この場合、静的変数statObjは最初のものとして初期化されます。したがって、私が正しければ、静的オブジェクトstatObj = new A()が最初のものとして作成されます。

この内部静的オブジェクトの作成と初期化の順序は? 内部静的オブジェクト コンストラクターが呼び出される前に、statObj.x の既定値が 0 で初期化されていませんstatObj.A()か? その場合、なぜ statObj.x が初期化されていないように動作するのですか (デフォルトで 0 の値で初期化されたと私は戦いました)。

もう1つ、この問題がメソッドではなくコンストラクタでのみ発生するのはなぜですか? 次のコードは正常に動作します。

        class A
        {
            A()
            {  
            }

            void met1()
            {
                statObj.x = 5; 
            }

            int x;
            static A statObj = new A();
        }


        public MainClass
        {
            public static void main(String[] arg)
            {
                A a = new A();
                a.statObj.met1();
            }
        }
4

4 に答える 4

9

何が起こるか考えてみてください。次の静的初期化子:

static A statObj = new A();

を呼び出しA()、次に にアクセスしようとしますstatObj

A() {
  statObj.x = 5; 
}

ただし、この時点statObjでは はまだ初期化されていないため、 ですnull。ANullPointerExceptionがスローされ、それが an に変換されますExceptionInInitializerError(NPE静的イニシャライザで発生したため)。

statObj2 番目の例では、 にアクセスしようとする時点で完全に初期化されているため、この問題は発生しません。

于 2012-12-12T11:36:11.130 に答える
0

問題は、このスタティックを含むコンストラクタでスタティックを初期化したことです。

適切に終了するには、construcorにその静的な値を設定する必要があります。しかし、その静的な値の構築を行うには、最初に終了する必要があります。

于 2012-12-12T11:38:30.247 に答える
0

オブジェクト (statObj.x) が作成される前にアクセスしようとしています。代わりにこれを試してください:

class A
{
    A()
    { 
    }

    int x;
    static A statObj = new A();

    static {
        statObj.x = 5;
    }
}
于 2012-12-12T11:37:03.067 に答える
0

オブジェクトが作成される前に静的フィールドに格納されているインスタンスにアクセスしようとしているため、NullPointerException が発生しています。これは、コンストラクターが完了した後にのみ作成されるために発生しています。しかし、コンストラクター内からこれを呼び出しています。

2 番目のコードは正常に動作します。これは、コンストラクター (何もしない) が完了する可能性があるためです。

また:

 static A statObj = new A();

statObjnew A()コンストラクター ( ) が完了するまで null になります。

新しいオブジェクトを作成する場合、作成の順序は次のようになります。 - A.class ファイルの検索 - 静的変数の初期化 - 非静的変数のデフォルトの初期化 - オブジェクトの割り当てメモリ - 非静的変数の明示的な初期化 - コンストラクターの実行

ここでの問題は、「静的変数の初期化」中に、同じ静的変数を使用しようとするコンストラクターを呼び出し、必要に応じてシーケンスを少し先に進めていることです。

では、statObj を作成するとき、statObj コンストラクターが呼び出される前に、statObj.x をデフォルトで初期化 (0 で) すべきではありませんか?

はい、しかしそれはここでの問題ではありません。ここでの問題はstatObj、コンストラクターが終了する前にそれ自体が null になることです。

statObj.x = 5;

もしそうならthis.x、それはうまくいくでしょう。しかしstatObj、その時点ではまだ null です。

于 2012-12-12T11:35:56.460 に答える