料AboutJavaScriptを有効にして、ご利用ください。クラスの初期化(initialization)とは、その静的初期化子とそのクラスの中に宣言されているstaticフィールド(クラス変数)に対する初期化子の実行からなる処理である。言い換えると、staticフィールドが存在すると、クラスの初期化が開始されるということである。staticフィールドはクラスが初期化されていることに依存する場合が考えられ、その場合、初期化が循環することになる。Java言語仕様§8.3.2.1「クラス変数の初期化子」には次のように記されている。static変数がfinalとして宣言されており、かつコンパイル時の定数値で初期化される場合、それは実行時に最初に初期化される。この一文は誤解を招くおそれがある。finalフィールドの値を使用するインスタンスには当てはまらないからである。宣言するだけでは、値が読み取られる前に完全に初期化されることを保証できない。プログラム一般、セキュリティに配慮すべきプログラムでは特に、クラスの初期化を循環させてはならない。(クラス内循環)以下の違反コード例には、クラス内の初期化循環がある。クラス変数を宣言しており、このクラス変数はCycleクラスのインスタンスに初期化される。宣言されたクラスメンバやコンストラクタの最初の呼び出しより前に1度だけ呼び出されることが保証されている。プログラマの意図は、預金額(deposit)から手数料(10)を引き、口座の残額(balance)を計算することにある。クラス変数cの初期化はdepositフィールドが初期化される前に行われる。クラス変数cの初期化はソースコード上、depositフィールドより前に現れるからである。したがって、cの静的初期化時に呼び出されるコンストラクタから見えるdepositの値は、初期値0であって、ランダムな値ではない。結果として、残額(balance)の計算結果は常に-10になってしまう。Java言語仕様では、このような再帰的な初期化の循環を実装上無視してもよいと認めている。(クラス内循環)以下の適合コードでは、クラスCycleのメンバフィールドの初期化順序を変更し、初期化の循環を発生させずにフィールドが初期化されるようにしている。具体的には、ソースコード上、cの初期化をdepositの初期化の後に置き、depositの初期化が完了した後でクラスが初期化されるようにしている。}}このような初期化循環の問題は、関係するフィールドが増えるほど気づかれにくくなる。したがって、プログラムの制御フローにこのような循環が発生しないようにすることは重要である。上述の適合コードのように修正すれば初期化循環は防げるが、宣言の順序に依存しており脆弱である。コードを後日メンテナンスするプログラマは、プログラムが正しく動作するにはこの宣言順序を保たなくてはならないことに気づかないかもしれない。したがって、このような依存性が存在することはコードの中にはっきりコメントとして残しておくべきである。(クラス間循環)以下の違反コード例では、静的変数を持つ2つのクラスを宣言しており、これらの変数は互いに依存している。2つのクラスをあわせて眺めると循環が存在することは明白だが、別々に眺めれば容易に見落としてしまうであろう。...}クラスの初期化順序が異なれば、計算されるA.aとB.bの値も異なる。クラスAが先に初期化される場合、A.aの値は2になり、B.bの値は1になる。クラスBが先に初期化される場合、値は逆になる。(クラス間循環)以下の適合コードでは、変数の依存関係を解消することでクラス間の循環を断ち切っている。初期化循環は予期せぬ結果をもたらす可能性がある。initialization翻訳元これは以下のページを翻訳したものです。有このページは役に立ちましたか?javascriptを有効にすると、ご回答いただけます。その他のご意見はPCサイトにて入力願います。