静的初期化ブロックは、JVMがクラスを初めて読み込む際に、クラスの静的メンバーが初めて使用される前に実行されるコードブロックです。
背景:
Javaは初めから、すべてのインスタンスで共通の値を保持するための静的フィールドを提供していました。カスタム初期化やクラスの起動時の複雑な計算のために、staticブロックが導入されました。
問題点:
通常の静的フィールドは宣言時に直接初期化できますが、初期化に時間がかかる場合や、他のクラス/ファイル/データベースへのアクセスが必要な場合、または複雑なロジックに依存する場合は、staticブロックを使用せざるを得ません。staticブロックの不適切な使用は、クラスのロード時の予期しない動作やテストの困難さ、さらにはデッドロックを引き起こす可能性があります。
解決策:
staticブロックは、単一の式では表現できない静的リソースの複雑な初期化にのみ使用します。良い例は、JDBCドライバーの読み込みや設定の読み取りです:
public class Config { public static Properties properties; static { properties = new Properties(); try (InputStream in = new FileInputStream("config.properties")) { properties.load(in); } catch (IOException e) { throw new ExceptionInInitializerError(e); } } }
主な特徴:
静的ブロック内でreturnを使用できますか?
いいえ、staticブロック内でのreturn文は許可されていません。例外をスローするためにthrowを使用できます。
静的ブロックは、クラスの読み込み時に実行されますか、それともオブジェクトの作成時に実行されますか?
静的ブロックは、クラスが読み込まれる際に1回実行され、オブジェクトが作成されなくても実行されます。
1つのクラスに複数のstaticブロックを持つことができますか?それらはどのような順序で実行されますか?
はい、複数の静的ブロックを宣言できます。これらはクラスのコード内での出現順に実行されます。
クラス内のstaticブロックが大きなファイルを読み込み、外部サービスに接続する。テストや単純なユーティリティではJVMのクラスの読み込みが遅くなる。
利点:
欠点:
静的ブロックは、起動時にソフトウェアライセンスを確認し、エラーが発生した場合はExceptionInInitializerErrorをスローします。
利点:
欠点: