18

Javaの静的ブロックは、そのクラスがロードされたときに1回だけ実行されると言われています。しかし、それは実際にはどういう意味ですか?クラスはどの時点でJVM(Java仮想マシン)によってロードされますか?

そのクラスのメインメソッドが呼び出されたときですか?また、mainメソッドの実行開始時に、同じクラスのすべてのスーパークラスも読み込まれるのでしょうか。

AがBを拡張し、BがCを拡張するとします。すべてに静的ブロックがあります。Aにメインメソッドがある場合、静的ブロックの実行シーケンスはどうなりますか?

4

3 に答える 3

10

これについては、JLSの実行セクションで説明されています。すなわち:

クラスの初期化は、その静的初期化子と、クラスで宣言された静的フィールドの初期化子の実行で構成されます。インターフェイスの初期化は、インターフェイスで宣言されたフィールドの初期化子を実行することで構成されます。
クラスを初期化する前に、その直接のスーパークラスを初期化する必要がありますが、クラスによって実装されるインターフェースを初期化する必要はありません。同様に、インターフェイスのスーパーインターフェイスは、インターフェイスを初期化する前に初期化する必要はありません。

したがって、この例では、「最上位」クラス(C)の静的ブロックが最初に実行され、次に、の静的ブロックが実行されB、次に最も派生したクラスが実行されます。

クラスのロードに入るすべてのステップの詳細な説明については、そのドキュメントを参照してください。

(クラスは、最初にアクティブに使用されたときにロードされます。)

于 2011-12-18T08:16:50.027 に答える
2

次の例ですべての問題が解決すると思います。

クラスが初期化される前に、そのスーパークラスは、以前に初期化されていない場合は初期化されます。

したがって、テストプログラムは次のようになります。

class Super {
        static { System.out.print("Super "); }
}
class One {
        static { System.out.print("One "); }
}
class Two extends Super {
        static { System.out.print("Two "); }
}
class Test {
        public static void main(String[] args) {
                One o = null;
                Two t = new Two();
                System.out.println((Object)o == (Object)t);
        }
}

プリント:

Super Two false

クラスOneはアクティブに使用されないため、初期化されることはなく、したがってリンクされることもありません。クラス2は、そのスーパークラスSuperが初期化された後にのみ初期化されます。

詳細については、このリンクをご覧ください

詳細の編集:紛らわしい行を削除しました。

于 2011-12-18T08:29:29.360 に答える
1

Java言語仕様から:

クラスの初期化は、その静的初期化子と、クラスで宣言された静的フィールド(クラス変数)の初期化子の実行で構成されます。インターフェイスの初期化は、そこで宣言されたフィールド(定数)の初期化子を実行することで構成されます。

クラスを初期化する前に、そのスーパークラスを初期化する必要がありますが、クラスによって実装されたインターフェイスは初期化されません。同様に、インターフェイスのスーパーインターフェイスは、インターフェイスが初期化される前に初期化されません。

このプロセスについては、 Java仮想マシンの仕様で詳しく説明されています。

于 2011-12-18T08:19:38.460 に答える