一般に、非静的な初期化ブロックを使用しないでください(静的なブロックも避けてください)。
わかりにくい構文
この質問を見ると、3つの答えがありますが、この構文で4人をだましています。私はそのうちの1人で、Javaを16年間書いてきました!明らかに、構文は潜在的にエラーを起こしやすいです!私はそれに近づかないでしょう。
テレスコープコンストラクター
本当にシンプルなものについては、「テレスコープ」コンストラクターを使用してこの混乱を回避できます。
public class Test {
private String something;
// Default constructor does some things
public Test() { doStuff(); }
// Other constructors call the default constructor
public Test(String s) {
this(); // Call default constructor
something = s;
}
}
ビルダーパターン
各コンストラクターまたはその他の高度な初期化の最後にdoStuff()が必要な場合は、おそらくビルダーパターンが最適です。 Josh Blochは、ビルダーが良いアイデアであるいくつかの理由をリストしています。ビルダーは書くのに少し時間がかかりますが、きちんと書かれていれば、使うのが楽しいです。
public class Test {
// Value can be final (immutable)
private final String something;
// Private constructor.
private Test(String s) { something = s; }
// Static method to get a builder
public static Builder builder() { return new Builder(); }
// builder class accumulates values until a valid Test object can be created.
private static class Builder {
private String tempSomething;
public Builder something(String s) {
tempSomething = s;
return this;
}
// This is our factory method for a Test class.
public Test build() {
Test t = new Test(tempSomething);
// Here we do your extra initialization after the
// Test class has been created.
doStuff();
// Return a valid, potentially immutable Test object.
return t;
}
}
}
// Now you can call:
Test t = Test.builder()
.setString("Utini!")
.build();
静的初期化ループ
以前は静的イニシャライザをよく使用していましたが、クラスが完全にロードされる前に呼び出される2つのクラスが互いの静的イニシャライザブロックに依存するループが発生することがありました。これにより、「クラスのロードに失敗しました」または同様にあいまいなエラーメッセージが生成されました。問題が何であるかを理解するために、ファイルをソース管理の最後の既知の作業バージョンと比較する必要がありました。まったく面白くない。
遅延初期化
静的イニシャライザは、パフォーマンス上の理由から、動作する場合に適切であり、混乱を招かないかもしれません。しかし、一般的に、最近では静的初期化子よりも遅延初期化を好んでいます。それらが何をするのかは明らかで、私はまだそれらのクラスローディングのバグに遭遇しておらず、それらはイニシャライザブロックが行うよりも多くの初期化状況で動作します。
データ定義
データ構造を構築するための静的な初期化の代わりに(他の回答の例と比較して)、Paguroの不変のデータ定義ヘルパー関数を使用します。
private ImMap<String,String> days =
map(tup("mon", "monday"),
tup("tue", "tuesday"),
tup("wed", "wednesday"),
tup("thu", "thursday"),
tup("fri", "friday"),
tup("sat", "saturday"),
tup("sun", "sunday"));
けいれん
Javaの初期では、初期化ブロックはいくつかのことを行う唯一の方法でしたが、今では混乱しやすく、エラーが発生しやすく、ほとんどの場合、より優れた代替物に置き換えられています(上記を参照)。レガシコードでそれらを見る場合、またはテストで出てくる場合にイニシャライザーブロックについて知ることは興味深いですが、コードレビューを行っていて、新しいコードで1つを見た場合、なぜ上記の代替案は、コードを評価する前に適切でした。