2012-03-12 11 views
10

初期化の順番を理解するのに問題があります。これは私が仮定ためです:イニシャライザブロックや変数定義などはどのような順序で実行されますか? (javaで)

*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; 
+0

どのコンパイラを使用していますか? Oracles javac?またはいくつかのIDE(少なくともEclipseは独自のコンパイラを持っています) –

+0

EclipseとOracles javacはこのシナリオで同じように動作します。 – aioobe

+1

eclipseを使用しています。 – Untitled

答えて

4
Java言語仕様(セクション8.3.2.3)を使用すると、左側に変数を使用することができます言う

それが宣言される前に式の手前側に割り当てられます。ただし、それを右辺で使用することはできません。

すべての変数はデフォルト値に初期化され、明示的なイニシャライザと無名ブロックはソースファイル内の順に実行されます。最後にコンストラクタが呼び出されます。

スタティックは、クラスの最初の使用時に一度だけ実行されます。

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

+0

フォローアップの質問: 私はここで状況を理解しています。なぜそのような機能があるのか​​理解できません。私はそれのための使用を想像することはできません。なぜ誰かがその宣言の前に初期化ブロックの変数に代入したいのですか?なぜそれを最初に宣言しないのですか? – Untitled

+1

私は同意し、なぜそれに値を割り当てることができますが、そこから読み取ることはできません。 JLSは、明示的なコードが実行される前にすべての変数が作成され、デフォルト値に初期化されているので、変数は存在し、その値は読み込めません。それはちょうど私には不思議そうです。 –

+0

循環参照を避けるためです。例えば。 int a = b + 1; int b = a + 2; – ekaerovets

1

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

int b = 0; // executed first 

{ 
    b = 1; // executed second 
} 

int a = b; // executed third 

宣言即ちint bを実行しないことに注意します。宣言はただ変数の存在を宣言します。

エラーが発生しましたか(またはエラーではなくを取得していません)私はそれが奇妙に見えることに同意します。私は、コンパイラが式の中の変数を参照し、その変数に異なる方法で値を割り当てることを扱っていると仮定します。インスタンスイニシャライザの変数に書き込むときは、変数がそこにあるかどうかをチェックするだけで、読み込み時にインスタンスの初期化子ブロックの上に宣言する必要があります。私はJLSでそれについての参考文献を見つけることができるかどうかを見ていきます。

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 
+1

しかし、なぜ彼は行の下で宣言された変数に書き込むことができますが、同じ変数から読み取ることはできません。 – aioobe

関連する問題