Javaクラスの静的メンバーはどのような順序で読み込まれる?JVMの処理手順を解説
Javaにおいて、静的変数(static変数)はクラスがロードされるタイミングで生成されます。これは静的ブロック(staticブロック)が実行されるよりも前の段階であり、静的ブロックの主な役割は静的変数に値を代入することです。
静的変数には、定義されたクラスのすべてのインスタンス間で共有される値が格納されます。一方、静的ブロックとは、クラスが最初にロードされるときに一度だけ実行されるコード領域のことです。したがって、クラスロード時に実行したい初期化処理やロジックがある場合は、その処理を静的ブロック内に記述しておくことで、クラスのロード時に確実に実行させることができます。
JVMが静的メンバーを読み取る手順
JVM(Java Virtual Machine)は、以下の3つのステップに従ってクラス内の静的メンバーを処理します。
- 静的メンバーの識別: クラス内の静的メンバーを上から下へ順番に認識します。
- 静的変数の代入と静的ブロックの実行: 静的変数への値の代入および静的ブロックを、ソースコードの記述順(上から下)に従って実行します。
- mainメソッドの実行: 最後にプログラムのエントリポイントであるmainメソッドを実行します。
サンプルコード
次の例では、静的変数・静的ブロック・mainメソッドが混在したクラスを定義し、実際の実行順序を確認できます。
public class StaticFlow {
static int firstNumber = 10;
static {
firstMethod();
System.out.println("first static block");
}
public static void main(String[] args) {
firstMethod();
System.out.println("main method executed");
}
public static void firstMethod() {
System.out.println(secondNumber);
}
static {
System.out.println("second static block");
}
static int secondNumber = 20;
}実行結果
0 first static block second static block 20 main method executed
実行結果の解説
一見すると意外に思われるかもしれませんが、出力の1行目が「0」になっている点に注目してください。この挙動は、前述のJVMの処理手順で正確に説明できます。
- JVMはまず、
firstNumberとsecondNumberという静的変数を識別します。この時点で両方の変数はメモリ上に作成され、それぞれデフォルト値(intの場合は0)で初期化された状態になります。 - 次に、上から下へ初期化処理が進みます。
firstNumber = 10の代入が完了した後、最初の静的ブロックが実行され、内部でfirstMethod()が呼び出されます。しかし、この時点ではsecondNumber = 20の代入はまだ行われていないため、secondNumberにはデフォルト値の0が出力されます。 - 続いて「first static block」、2番目の静的ブロックによる「second static block」が順に出力され、その後
secondNumber = 20の代入が完了します。 - 最後にmainメソッドが実行され、今度は代入済みの20が出力された後に「main method executed」が表示されます。
このように、静的メンバーは「識別 → 初期化(代入と静的ブロック)→ mainメソッド実行」という厳密な順序で処理されるため、静的ブロック内から参照できる静的変数の値は、その時点での初期化状況に依存することを理解しておくことが重要です。
-
Java 9における@Deprecatedアノテーションの改善点とは?新要素「since」「forRemoval」を徹底解説
@Deprecatedアノテーションとはクラス、メソッド、フィールドなど、プログラム内のあらゆる要素に付与できる@Deprecatedアノテーションは、「その要素はもはや使用すべきではない」ことを示すためのものです。要素が非推奨とされる主な理由は以下の通りです。使用すると危険であり、エラーを引き起こす可能性がある将来のバージョンで互換性がなくなる可能性がある将来のバージョンで削除される可能性があるより優れた、効率的な代替手段がすでに提供されているJava 9で追加された2つの新しい要素Java 9では、@DeprecatedアノテーションにsinceとforRemovalという2つの新しい属性
-
JavaにおけるCursorクラスの役割とは?マウスカーソル制御の基本を解説
JavaのCursorクラスとはCursorクラスは、Objectクラスのサブクラスであり、画面上のポイント(指し示す位置)やインジケーター(表示標識)として定義されます。ユーザーがマウスを使ってシステムへの入力を選択・操作する際に、その位置を視覚的に示す重要な役割を担っています。GUIアプリケーションでは、状況に応じてカーソルの形状を変えることで、ユーザーに対して直感的なフィードバックを提供できます。例えば、処理中であることを伝える砂時計型のカーソルや、クリック可能な要素を示す手型のカーソルなどが代表的な例です。利用可能なカーソルの種類Cursorクラスには、あらかじめ定義されたさまざまなカ