2017-05-20 18 views
0

次のコードは正常にコンパイルされます。私の理解あたりとして変数は、まさにここに静的初期設定子の後に静的変数を宣言する

class A { 
static { 
    y=20; 
    z=10; 
} 
static int z; 
static int y=30; 
{ 
    w=10; 
} 
int w; 
public static void main(String args[]){ 
    System.out.println(y); 
} 
} 

が起こっているし、それらを使用する前に宣言する必要のコメントを読んだ後、質問を変更しました。 ここで、出力は30 そこで変数宣言は、すべての初期設定ステートメントは、それがクラスをロードするとき

+1

* "私の理解によれば、変数は宣言する必要があります" *なぜブロックと変数の配置がここで重要と思われますか? – Tom

+2

*ローカル*変数は、最初に使用する前に宣言する必要があります。フィールド数はあまり多くはありません... –

+1

両方のリンクは重複としては機能しませんが、(暗黙のうちに)フィールドのプレースメントはさまざまです:[インスタンス変数の宣言の配置](// stackoverflow.com/q/218573) // [Javaのベストプラクティス - クラス変数の前にコンストラクタを宣言していますか?](// stackoverflow.com/q/10264447) – Tom

答えて

1

変数は彼らに

を使用する前に宣言する必要が本当に問題ではありません

これは部分的にしか正しくありません。あなたが方法にいる場合、あなたはこれを行う:

System.out.println(i); 
int i = 0; 

明らかにそれはコンパイルされません。

しかし、クラスレベルで変数を宣言している場合、このルールは成立しません。あなたのコードでは、wの宣言が使用されてから数行(w = 10;)だけ書かれているため、int w;という行がw = 10;の後に実行されるわけではありません。

このように考えると、コンパイラはすべての静的フィールドの宣言(クラスレベル変数)、次にすべての非静的フィールド、次にクラスのコードブロック(コンストラクタ、メソッドなど)を表示します。あなたのコードでは:

class A { 
    static { 
     z=10; 
    } 
    static int z; 
    { 
     w=10; 
    } 
    int w; 
} 

コンパイラは、zまず、wを見ています。次に、コードの他の部分で初めてAにアクセスしたとします。これで静的ブロックが実行されます(z=10;)。もう一度、実際にAの新しいインスタンスを作成していて、今度はw=10;が実行されるとします。

+0

完全性のための質問を修正しました – wib

+1

@wibあなたが直面した動作は、静的ブロックの後に 'int y = 30;'のような文が実行されるためです。したがって、コンパイラは最初に宣言を見てから、静的ブロックを実行し、次に 'y = 30'部分を実行します。 – Sweeper

1

変数は、クラスローダによって宣言された出現の順序に従って実行され、最初に発生しています。

静的ブロックは、その時間内にメンバ変数が宣言されますので、クラスに最初にアクセスした際に評価されますので、注文は

+0

が質問を修正しました。変数が宣言され、1つのステートメントで初期化されるとどうなりますか? – wib

関連する問題