は、なぜ私は、静的なブロックを使用することになりなぜインスタンス変数を直接初期化するよりも静的ブロックを使用するのですか?</p> <pre><code>static { B = 10; } </code></pre> <p>オーバー:
Integer B = 10;
他の上の1つの長所/短所は何ですか?
は、なぜ私は、静的なブロックを使用することになりなぜインスタンス変数を直接初期化するよりも静的ブロックを使用するのですか?</p> <pre><code>static { B = 10; } </code></pre> <p>オーバー:
Integer B = 10;
他の上の1つの長所/短所は何ですか?
静的イニシャライザブロックは、必要なときにのみ使用してください。たとえば、フィールドの最終的な値を計算するためにいくつかの手順を実行する必要がある場合があります。方法は混乱するかもしれないので、私は、静的なブロックを好むこの場合
static final Integer B;
static {
int temp = ...;
...
B = temp;
}
:値を計算する方法を記述しstatic final Integer B = calculateB()
として、あなたのフィールドを宣言し、または初期化子ブロックを使用します。この場合、次の2つのチャンスを持っています(他の開発者は、初期化中に一度だけ呼び出されることを意図していますが、他の開発者はその呼び出しを試みる可能性があります)。
通常は例外的な初期化ブロックを避け、単にフィールドの初期化ロジックをコンストラクタに書き込むこともできますが(もちろん静的フィールドでは不可能ですが)、インスタンスフィールドにも同じことが適用されます。
スタティック初期化は、クラスのロード時に発生します。
など。複数のスレッドによるアクセスのために同期が必要なメンバー変数を初期化するのが適切な場所になります。
コンストラクタを明示的に呼び出すと、2番目のケースが発生します。
使用方法が異なります。
など。あなたは何かの怠惰な読み込みのための2番目のケースを好むだろう(もしそれが常に読み込まれる静的なイニシャライザに入れて、それを望んでいないのであれば) -
違いを理解できませんか?確かにクラスを読み込むことは、そのコンストラクタを呼び出すことと同じですか? –
いいえ、絶対にありません。たとえば、クラスで静的メソッドを呼び出すと、クラスがロードされますが、コンストラクタは実行されません。 – DNA
static
ブロックは、属性の初期化ロジックですが、1行の初期化では1つの式に制限されます。
初期化ブロックはこの1つのインスタンス化時にインスタンス属性初期化し、例えば、インスタンスと静的の両方の属性に存在することに注意してください:これは、クラスのロード時に静的属性を初期化するのに対し
private int a;
{ a = 10; }
を:
private static int b;
static { b = 10; }
初期化手順の詳細は、hereでJVM仕様の一部として説明しています。
まず、Integer B
は静的ではないメンバー変数で、静的ブロックからはアクセスできません。だから、どちらかあなたは例外が発生したりするための特別な方法を記述することなく、より複雑な何かができる値でBを初期化するためにそれを使用することができますどちらの場合も
//Initialize static field
static {
B = 10;
}
static Integer B = 10;
または
//Initialize member field
{
B = 10;
}
Integer B = 10;
を書くことを意味しその中に。
{
try{
B = thisWillThrowAFileNotFound();
}catch(FileNotFoundException){
B = 10;//Set default
}
}
実は、あなたが
private static Integer B = 10;
を持っている場合、コンパイラは、基本的に翻訳します:
private static Integer B;
static {
B = 10;
}
静的ブロックを持つことは、あなたが全体の言語を使用できることであるだけではなく、初期化を行う式。あなたはあなたが行うことができ7の倍数の束を持つ配列必要があると想像:とにかく
private static Integer[] array;
static {
array = new Integer[1000];
for (int i = 0; i < 1000; i++) {
array[i] = 7 * i;
}
}
を、あなたも、このようにそれを行うことができます:
private static Integer[] array = initArray();
private static Integer[] initArray() {
Integer[] result = new Integer[1000];
for (int i = 0; i < 1000; i++) {
result[i] = 7 * i;
}
return result;
}
これはAの答えの少ない、よりです警告...静的イニシャライザは合成clinit(){クラスinit}メソッドで実行されます。*暗黙的に同期されます*。したがって、静的イニシャライザ内で呼び出すコードは、マルチスレッドアプリケーションではクラスファイルのロードにデッドロックが発生する可能性があるため注意が必要です。 制御できない、または理解していない他のクラスを呼び出す必要がある場合は、クラスをロードするまでプロバイダの抽象化を使用して初期化を遅らせることができます。 – Ajax