静的initブロックがどのように機能するかを知っています。
誰かがそれのいくつかの典型的な使用法を教えてもらえますか?
7 に答える
1つ以上の静的変数を1か所で初期化する場合
インライン初期化では不可能な例外処理を適用できるので便利です。
例えば:
public static ImageIcon defaultIcon = ImageIO.read(..);
で初期化できます
public static ImageIcon defaultIcon;
static {
try {
defaultIcon = ImageIO.read(..);
} catch (IOException ex){
System.out.println("No default icon available");
}
}
もう1つのアプリケーションは、複雑な初期化です。たとえば、アイテムの初期化に複数行のコードが必要な場合です。構成があるとしましょう:
public static Configuration configuration;
static {
confuguration = new Configuration();
configuration.setSomething(..);
configuration.setSomethingElse(..);
...
}
3番目の使用法は、いくつかの外部APIインフラストラクチャを初期化することです。私の現在のプロジェクトからの一例:
static {
org.apache.xml.security.Init.init();
}
ただし、Mykola Golubyevが指摘したように、静的初期化ブロックはコードを読みにくくするため、注意して使用してください。静的メソッドは同じことをより透過的に行います。
静的初期化ブロックの使用を避けるようにしてください。代わりに、コードをよりクリーンにするプライベート静的初期化関数を使用できます。
例として@Bozhoを参照します。
するな
public static Configuration configuration;
static {
confuguration = new Configuration();
configuration.setSomething(..);
configuration.setSomethingElse(..);
...
}
代わりに使用してください
public static Configuration configuration = createConfiguration();
また
public static Configuration configuration = YourConfiguration.create();
これらは、必要なネイティブライブラリが確実にロードされるようにするためにJNIコードと組み合わせて使用されることがよくあります。
class MyJniConnection {
public static native void myJniCall();
static {
System.load("native.dll");
}
}
- Map、List、Setなどのコレクション静的フィールドを初期化する
- 静的でもあるセッターベースのオブジェクトを初期化する
JDBCドライバーは人気のある例です
なぜClass.forName()
ドライバをメモリにロードする必要があるのですか。答えは簡単です。JDBC仕様で規定されているように、すべてのJDBCには、クラスがロードされるとすぐDriver
に登録する静的ブロックがあります。このようなもの:DriverManager
Driver
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
したがって、次のように記述します(たとえば、ここではMySQLドライバーを使用します)。
Class.forName("org.gjt.mm.mysql.Driver");
クラスローダーはクラスをロードしてリンクしようとします。org.gjt.mm.mysql.Driver
成功すると、静的初期化ブロックが実行され、Driver
それ自体がに登録されますDriverManager
。
JMockと同様に、DSLを作成するために使用できます。たとえば、ユーザーがデータベースに保存されるという期待を設定するには、次のようにします。
Mockery context = new Mockery();
final Database database = context.mock(Database.class);
...
context.checking(new Expectations() {{
oneOf(database).save(user);
}});
// Rest of the test
- 静的ブロック:-クラスのロード時にコードを実行する場合は、コードを静的ブロックに配置できます...
- init:-クラスのオブジェクトの開始時にコードを実行したい場合は、コードをinitブロックに入れることができます...。