次のシナリオでは、
import A;
public class B{
static A a;
static{
a = new A();
}
}
static initialization block
前に呼び出される取得a
が適切に初期化される可能性はありますか? 注:A
これはロギング フレームワークです。
次のシナリオでは、
import A;
public class B{
static A a;
static{
a = new A();
}
}
static initialization block
前に呼び出される取得a
が適切に初期化される可能性はありますか? 注:A
これはロギング フレームワークです。
上記の場合、クラスのロード時に静的ブロックが呼び出されるため、Aが初期化される前に静的ブロックが呼び出されます(この場合はクラスB)。だからあなたがするとき
B.someStaticMethod()
最初のクラス B は、静的ブロックが呼び出される場所 (JVM での 1 回のプロセス) にロードされ、次に静的メソッドが呼び出されます。
また、クラスをロードする Importing ステートメントはクラスをロードしないことに注意してください。そのクラスで何らかの操作を行うと発生します。
まず、確実ではありませんが、A が「適切に初期化される」前に静的初期化子が呼び出される可能性があります。B がクラスローダによってロードされると、静的イニシャライザが実行されます (#9: http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2を参照)。 )。あなたが与えた情報から、A のロードに関連してそれがいつ発生するかを知るのに十分な情報がありません (B の静的初期化子でのコンストラクターの呼び出しは、A が初めてロードされたときか、ずっと前に発生した可能性があります)。
第二に、初期化されている A のインスタンスが A の初期化をトリガーして、すべてがうまくいく可能性が非常に高いです。A のコンストラクターは、クラスが読み込まれるまで実行されないことに注意してください。これには、A の静的イニシャライザーの実行が含まれます。
第三に、インポート文はこれとは何の関係もありません。完全修飾 com.foo.A が import ステートメントを使用したかどうかにかかわらず、同じように動作します。
最後に、実際の例を提供していただけると助かります。A が単なるロギング フレームワークである場合、それは独自のものではなく、その特定のフレームワークで実際に何が起こるかに基づいて、より役立つ答えが得られるでしょう。
編集: 具体的な例については、以下のコメントにあるリンクを参照してください。
クラスは任意の数の静的初期化ブロックを持つことができ、クラス本体のどこにでも表示できます。ランタイム システムは、静的初期化ブロックがソース コードに現れる順序で呼び出されることを保証します。
そのため、A が適切に初期化される前に静的ブロックが呼び出されることはありません。
インスタンスを次のように初期化しても混乱はないと思いますstatic
-
static A a = new A();
静的A a; static { a = 新しい A(); このコードが明確に意味することは、コード a = new A(); です。一度だけ呼び出されて初期化され、クラスがロードされたときにメインスレッドがシステムから終了するまで永久に生成されたままになります。