静的ブロック
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 17/87。
時には、単純な代入よりも複雑なロジックで静的変数を初期化する必要がある場合があります。staticブロック(静的初期化子とも呼ばれます)は、クラスが最初にロードされたときに一度だけ実行され、オブジェクトが作成されたり静的メソッドが呼び出されたりする前に行われます。
public class DatabaseConfig {
private static String connectionString;
private static int maxConnections;
static {
// 複雑な初期化ロジック
connectionString = "jdbc:mysql://localhost:3306/mydb";
maxConnections = 10;
System.out.println("Database configuration loaded");
}
}staticブロックは、クラスがメモリにロードされるときに自動的に実行されます。これは、作成するオブジェクトの数に関係なく、一度だけ実行されます。複数のステートメント、計算、または条件付きロジックを必要とする初期化に最適です。
クラス内に複数のstaticブロックを持つことができ、それらは記述された順序で実行されます。
public class AppSettings {
private static int[] values;
static {
values = new int[5];
}
static {
for (int i = 0; i < values.length; i++) {
values[i] = i * 10;
}
}
}静的ブロックは、静的配列やコレクションの初期化、計算を必要とする設定値のセットアップ、およびクラスレベルでの一度限りのセットアップタスクの実行によく使用されます。
チャレンジ
簡単クラスが最初にロードされたときにゲーム設定を初期化するために、静的ブロック(static blocks)を使用する GameConfig システムを構築しましょう。これは、ゲームオブジェクトが作成される前に一度だけ計算またはセットアップが必要な設定に最適です。
コードを整理するために2つのファイルを作成します:
GameConfig.java: 静的ブロックを使用して設定を初期化する設定クラスを作成します:- 各レベルに到達するために必要なスコアを格納する、private staticな配列
levelThresholds(int[]) - レベルの総数を格納する、private staticな変数
maxLevel(int) - 初期化が行われたかどうかを追跡する、private staticな変数
configLoaded(boolean) - 静的ブロックを使用して
maxLevelを 5 に初期化し、"Initializing game configuration..."と出力します - 2つ目の静的ブロックを使用して、
maxLevelと同じサイズのlevelThresholds配列を作成し、各レベルにlevel * 100ポイント(レベル1は100、レベル2は200など)が必要になるように値を入れ、configLoadedをtrueに設定します - そのレベルのスコアしきい値を返す静的メソッド
getThreshold(int level)(レベルは1から始まります) - 最大レベルを返す静的メソッド
getMaxLevel() - 設定がロードされたかどうかを返す静的メソッド
isConfigLoaded()
- 各レベルに到達するために必要なスコアを格納する、private staticな配列
Main.java: クラスにアクセスしたときに静的ブロックが自動的に実行されることを示します。クエリするレベル番号という1つの入力を受け取ります。次の4行を出力してください:Config loaded: trueまたはConfig loaded: falseMax level: [maxLevel]Level [level] threshold: [threshold]Level 1 threshold: [threshold](常にレベル1も表示します)
1つの入力:クエリするレベル番号 (int) を受け取ります。
Mainのコードが実行される前に初期化メッセージが表示されることに注目してください。これは、クラスが最初にロードされたときに静的ブロックが実行されているためです!
チートシート
staticブロック(または静的初期化子)は、クラスが最初にロードされたときに一度だけ実行されます。これは、オブジェクトが作成される前、または静的メソッドが呼び出される前に実行されます。複数のステートメントを必要とする複雑な初期化ロジックに使用されます。
public class Example {
private static String value;
static {
// 初期化ロジック
value = "initialized";
System.out.println("Static block executed");
}
}staticブロックは、クラスがメモリにロードされたときに自動的に実行されます。作成されるオブジェクトの数に関係なく、一度だけ実行されます。
1つのクラス内に複数のstaticブロックを記述することができます。これらは記述された順序で実行されます:
public class Example {
private static int[] values;
static {
values = new int[5];
}
static {
for (int i = 0; i < values.length; i++) {
values[i] = i * 10;
}
}
}一般的な用途としては、静的配列やコレクションの初期化、計算を必要とする設定値のセットアップ、クラスレベルでの一度限りのセットアップタスクの実行などが挙げられます。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int level = scanner.nextInt();
// TODO: GameConfigにアクセスして、staticブロックの実行を確認する
// GameConfig内のstaticブロックは、クラスに初めてアクセスした際に自動的に実行されます
// TODO: 設定が読み込まれたかどうかを出力する
// 形式: "Config loaded: true" または "Config loaded: false"
// TODO: 最大レベルを出力する
// 形式: "Max level: [maxLevel]"
// TODO: 入力されたレベルのしきい値を出力する
// 形式: "Level [level] threshold: [threshold]"
// TODO: レベル1のしきい値を出力する
// 形式: "Level 1 threshold: [threshold]"
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造