静的フィールドはいつ初期化されますか?クラスをインスタンス化することは決してないが、静的フィールドにアクセスする場合、プライベートスタティックフィールドをインスタンス化するために使用されるすべての静的ブロックとプライベート静的メソッドは、その時点で(順番に)呼び出されますか?
静的メソッドを呼び出すとどうなりますか?すべての静的ブロックも実行しますか?メソッドの前に?
通常、クラスの静的初期化は、次のイベントのいずれかが最初に発生する直前に発生します。
JLS 12.4.1 を参照してください。
Class.forName(fqn, true, classLoader)
または短縮形 Class.forName(fqn)
)を使用して、クラスを強制的に初期化することもできます(まだ初期化されていない場合)。
1-Java 6からJava 8までのJLSに最後の箇条書きがありましたが、明らかに仕様の間違いでした。最終的に修正されました。 Java 9 JLS: source を参照してください。
静的フィールドは、静的初期化子とその静的フィールドの初期化を含む、クラスのロード(ロード、リンク、および初期化)の 初期化 「フェーズ」で初期化されます。静的初期化子は、クラスで定義されているテキストの順序で実行されます。
例を考えてみましょう:
public class Test {
static String sayHello() {
return a;
}
static String b = sayHello(); // a static method is called to assign value to b.
// but its a has not been initialized yet.
static String a = "hello";
static String c = sayHello(); // assignes "hello" to variable c
public static void main(String[] arg) throws Throwable {
System.out.println(Test.b); // prints null
System.out.println(Test.sayHello()); // prints "hello"
}
}
Test.bは、null
が静的スコープで呼び出されたときに、静的変数sayHello
が初期化されなかったため、a
を出力します。
はい、クラスに初めてアクセスする前に、すべての静的初期化子が実行されます。それが他の方法であれば、私はそれをバグと呼びます。