10

初期化が行われる順序を理解するのに問題があります。これは私が仮定した順序です:

*Once per 
    1. Static variable declaration
    2. Static block
*Once per object
    3. variable declaration
    4. initialization block
    5. constructor

しかし、このコードによると、私は明らかに間違っています:

    class SomethingWrongWithMe
    {
        {
            b=0;         //no. no error here.
            int a = b;   //Error: Cannot reference a field before it is defined.
        }
        int b = 0;
    }

そして、これを行うとエラーが消えます:

    class SomethingWrongWithMe
    {
        int b = 0;
        {
            b=0;
            int a = b;   //The error is gone.
        }
    }

エラーが出ない理由がわかりません

    b=0;
4

3 に答える 3

4

Java 言語仕様 (セクション 8.3.2.3) では、式の左側で変数を使用できます。つまり、変数を宣言する前に代入できますが、右側では使用できません。

すべての変数はデフォルト値に初期化され、次に明示的な初期化子と無名ブロックがソース ファイルで見つかった順序で実行されます。最後にコンストラクターが呼び出されます。

静的は、クラスの最初の使用時に 1 回だけ実行されます。

コンパイル エラーは、すべての場合に必ず意味のあるものではなく、Java のルールのようです。

于 2012-03-12T10:51:26.310 に答える
3

変数の定義は、ブロックの「前」には行われません。これらは、定義された順序で同時に実行されます。

class SomethingWrongWithMe {
    {
        b = debug("block 1");
    }
    int b = debug("define");
    {
        b = debug("block 2");
    }
    private int debug(String str) {
        System.out.println(str);
        return 0;
    }
}

出力

block 1
define
block 2
于 2012-03-12T10:39:33.090 に答える
1

int b = 0まず第一に、宣言( などの初期化を伴う)とインスタンス初期化ブロックが記述された順序で実行されるという事実を除いて、あなたの仮定は多かれ少なかれ正しいです。

int b = 0;   // executed first

{
    b = 1;   // executed second
}

int a = b;   // executed third

また、宣言ieint b実行されないことに注意してください。宣言は、変数の存在を宣言するだけです。

表示されたエラー (または表示されなかったエラー) については、奇妙に見えることに同意します。コンパイラは、式で変数を参照し、さまざまな方法で値を代入することを扱っていると思います。インスタンス初期化子で変数に書き込むときは、変数がそこにあることを確認するだけですが、変数から読み取るときは、インスタンス初期化子ブロックの上で宣言する必要があります。JLSでその参照を見つけることができるかどうかを確認します。

于 2012-03-12T10:34:16.867 に答える