以下のコードで混乱しています。エラーが発生するか、回答が 10 になると予想していましたが、どのように 20 を返していますか?
public class test {
public static void main(String[] args) {
System.out.println(x);
}
static{
x=10;
}
static int x=20;
}
以下のコードで混乱しています。エラーが発生するか、回答が 10 になると予想していましたが、どのように 20 を返していますか?
public class test {
public static void main(String[] args) {
System.out.println(x);
}
static{
x=10;
}
static int x=20;
}
JLS のセクション 12.4.2 で指定されており、クラスの初期化の詳細が示されています。
次に、クラスのクラス変数初期化子と静的初期化子、またはインターフェイスのフィールド初期化子を、単一のブロックであるかのように、テキストの順序で実行します。
変数初期化子 ( )は、プログラム テキスト内x = 20
の静的初期化子 ( を含むブロック) の後に発生します。x = 10
したがって、初期化の最後の値は 20 です。
変数の初期化子が最初になるように順序を入れ替えると、代わりに 10 が表示されます。
ただし、可能であれば、テキストの順序に依存するコードを記述しないことを強くお勧めします。
編集:変数はスコープ内にあるため、静的初期化子で引き続き使用できます-変数より前に宣言されたメソッドでインスタンス変数を使用できるのと同じです。ただし、セクション 8.3.2.3では、これについていくつかの制限が設けられています。
メンバーの宣言は、メンバーがクラスまたはインターフェイス C のインスタンス (それぞれ静的) フィールドであり、次のすべての条件が保持される場合にのみ、使用する前にテキストで表示する必要があります。
使用は、C のインスタンス (それぞれ静的) 変数初期化子または C のインスタンス (それぞれ静的) 初期化子で発生します。
使用法は割り当ての左側にありません。
使い方は単純な名前です。
C は、使用法を囲む最も内側のクラスまたはインターフェイスです。
上記の 4 つの要件のいずれかが満たされない場合、コンパイル時エラーになります。
したがって、静的イニシャライザを次のように変更すると:
static {
System.out.println(x);
}
その後、エラーが発生します。
ただし、既存の静的初期化子はx
、すべての制限に準拠する方法で使用します。
値が一度変更されると、静的に変更されます。だからあなたは20を取得しています。
このように書くと
public class test {
static int x=20;
public static void main(String[] args) {
System.out.println(x);
}
static{
x=10;
}
}
その後、10が出力されます。