2017-07-04 20 views
0

私はJavaで静的初期化子を研究しています。下記のように私は、ソースコードを来た:静的イニシャライザがJavaで静的変数の再初期化を許可するのはなぜですか?

public class A { 
     private static int count = 5; 
     final static int STEP = 10; 
     boolean alive; 
     static { 
     count = 1; 
     } 
     public static void main(String[] args) { 
      A a = new A(); 
      System.out.println(A.count); 
     } 
    } 

私の質問は、なぜコンパイラは、静的初期化子ブロックでcount = 1に値1を再割り当てされている変数count文句を言っていないことです。私は、Javaが宣言前読み取りルール(つまり、宣言の前にすべての識別子を読み取るべきではない)が続くことを前向きにしている限り、Javaは前方参照を許可していますが、すべての初期化子が参照されていなければ、参照割り当ての左側にある。私はまた、複数の静的初期化子式と静的フィールド初期化子ブロックがクラスに書き込まれている場合、その実行順序は順次であることも知っています。

私によれば、クラスはロードされてから、すべての静的初期化子(式とブロック)が順番に実行され、countは値5に初期化され、次にデフォルトのコンストラクタsuper()を呼び出し、インスタンス変数aliveをデフォルト値に初期化して実行されます。しかし、静的変数countが再初期化されたというエラー(なぜなら、前方参照の場合ではない)を出さない理由は、代わりに出力1です。 これは、静的変数を静的イニシャライザブロックで再初期化できるということですか?助けてください。前もって感謝します! :)

+3

どうすればよいですか? – EJP

+0

変数を再初期化しておらず、変数を再割り当てしています –

答えて

1

クラス内の静的変数を操作する限り、初期化されている間はコンパイラからエラーは発生しません。あなたが最後にそれを宣言していたなら、あなたが言及した行動が起こったはずです。静的とは、変数がオブジェクトのすべてのインスタンスで共有されるため、初期化され、メモリが一度だけ割り当てられることを意味します。

+0

ありがとう!コンセプトをクリアするのに役立ちましたコンストラクタとインスタンス初期化子で変数を再割り当てしようとしましたそれは働いた!:) –

+0

@パトリック1729すぐに、順序はここでは関係ありません。 –

1

使用する前にクラス変数が表示されているので、それは問題ありません。ここ

クラスが初期化されるとき、クラス内で宣言静的初期化子が(§12.4.2)が実行される同じ

ためlanguage specification#Static Initializersあります。クラス変数(§8.3.2)のフィールド初期化子とともに、静的初期化子を使用してクラスのクラス変数を初期化することができます。

宣言が使用後にテキストで表示されるクラス変数の使用は、これらのクラス変数が有効範​​囲内にあっても制限されることがあります。クラス変数への前方参照を規定する正確な規則については、§8.3.3を参照してください。

+0

補足:この問題では、初期化ブロックが宣言の前に表示される可能性があります。フィールドは代入の左側でのみ使用されます –

+0

両方ともありがとう、@ al3xkrによって与えられた答えはより明確で概念的です –

関連する問題