回答:
通常、クラスの静的初期化は、次のいずれかのイベントが初めて発生する直前に発生します。
JLS 12.4.1を参照。
Class.forName(fqn, true, classLoader)
または短縮形を使用して、クラスを強制的に初期化することもできます(まだ初期化されていない場合)。Class.forName(fqn)
1-最後の箇条書きは、Java 6からJava 8までのJLSに存在していましたが、仕様に間違いがあるようです。最終的にJava 9 JLSで修正されました。ソースを参照してください。
String
は置き換えられ、参照されません。class Other { public static final int VAL = 10; }
あるクラスのを参照するとMyClass { private int = Other.VAL; }
、そのクラスOther
は読み込まれません。代わりに、コンパイラーはコンパイル時に最終フィールドを単に置き換えます。
String
変数には当てはまりません。定数式によって初期化されたものだけです。
static
これは一般的なケースですが、フィールドは必須ではありません。
静的フィールドは、 、静的イニシャライザとその静的フィールドの初期化を含む、クラスのロード(ロード、リンク、および初期化)初期化「フェーズ」初期化されます。静的初期化子は、クラスで定義されているテキスト順に実行されます。
例を考えてみましょう:
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"
}
}
静的スコープで呼び出されnull
たときにsayHello
静的変数a
が初期化されなかったため、Test.bが出力されます。
はい、静的イニシャライザはすべて、クラスに初めてアクセスする前に実行されます。それ以外の方法であれば、私はそれをバグと呼びます。