2013-03-06 16 views
5

コンストラクタを使用して静的メンバーを初期化できるときに、なぜ静的初期化ブロックを使用する必要がありますか?Javaで静的初期化ブロックを使用するのはなぜですか?

+8

あなたはそのクラスのインスタンスを持っていませんが、スタティックイニシャライザブロックで初期化された値を使用する静的関数を使用したい場合はどうなりますか? – ppeterka

+1

とc'torが呼び出されるたびに、静的な値がリセットされます。悪い!! – Azodious

答えて

3

まず、クラスのインスタンスが1つもないことがあります。または、静的メンバーをに設定してから、の前にクラスのインスタンスを作成することもできます。

は第二に、コンストラクタから静的メンバを初期化することは、より多くの仕事です:

  • あなたはすべてのコンストラクタがこれを行うことを確認する必要があります。
  • 静的メンバーが初期化されているかどうかを追跡するフラグを維持する必要があります。
  • 競合状態を防ぐために同期について考える必要があります。
  • 同期のパフォーマンスへの影響を考慮する必要があります。特に、多くのスレッドでクラスのインスタンスが多数作成されている場合は、

最後に、それは通常、概念的(遅延初期化のための合法的な用途があるので、私は「普通」と言う)を行うには間違ったことです。

+0

+1 - 遅延(または非遅延遅延)初期化を実装しようとしていたとしても、おそらくコンストラクタで「起こさせる」ことはできません。 –

1

スタティックメンバは、クラスのインスタンスには関連付けられていませんが、コンストラクタはインスタンスを作成します。クラスのインスタンスを1つも持たずに静的メンバーを使用することができます。まだ初期化する必要があります。この場合、コンストラクタはジョブを実行できません。

0

なぜ:

static Set<String> digits = new HashSet<String>(); 
static { 
    Collections.add(digits, "unu", "du", "tri", "kvar", "kvin"); 
    digits.add("ses"); 
    digits.add("sep"); 
    digits.add("ok"); 
} 

次のことが可能である場合:

static Set<String> digits = new HashSet<String>() {{ 
    Collections.add(this, "unu", "du", "tri", "kvar", "kvin"); 
    add("ses"); 
    add("sep"); 
    add("ok"); 
}}; 
  1. それは、jarファイル内のファイルを新しい匿名クラスを紹介。それほど最適ではありません。
  2. 2番目の形式は奇妙な遊びです。
+0

なぜ新しい匿名クラスを導入するのが最適ではないのですか?バグをクラスロードすることになりますか?または単にあなたがあなたの瓶を膨らませたくないと言っていますか? @DavidT。 –

+1

どちらの形式も嫌いではありませんが、最初のものは 'digits'の冗長な出現を持ち、2番目のものは任意のクラス(小さなオーバーヘッド)を作成し、Java以外の開発者にとって誤解を招く構文を持っています。実際の危険は、シリアライズ可能なクラスに対して非静的な '{{...}}'を使用するときです:周囲のクラスgetの 'this'もシリアライズされます。私はこのような 'X.this'がオブジェクトの再読み込み後にnullになったことに遭遇しました。 –

+1

実際には、私は1つの違いを見つけました - > Eclipse上で、あなたが匿名のクラス内でクラッシュした場合、Eclipseはクラッシュのラインを指すプロジェクトも知りません(スレッドとランナブル匿名クラスとして) –

関連する問題