2

が、私はこれをコンパイルされたコードJavaコンパイラがフィールドの初期化を認識しないのはなぜですか?

int myVar; 
final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 
if (condition) { 
    System.out.println("myVar = " + myVar); 
} 

の以下の部分があると、私はmyVar might not have been initializedエラーを予想ました。 これはコンパイラのバグですか? conditionがtrueのときに "myVar"が設定されていて、conditionがtrueのときにのみ参照されることは容易に分かります。 (conditionも決してリセットされません)

P.S:0に初期化する必要がある私のコメントに、はい私はそれを認識しています。 (。つまり、値は高々一度設定)が、ポイントは、私が「myVarに」最終的なものにするJLSで説明したように、

+1

:コンパイラは、したがって、次の文でエラーを報告する義務があります初期化が必要です。 – azurefrog

+4

Javaコンパイラは、変数myVarが使用される前に常に値が変数myVarに割り当てられていると結論付けるのに十分深い分析をしません。一般に、異なる条件文で条件を相関させようとはしません。 –

+0

コンパイラが条件が変わらないことを認識しているとは思わない。例えば、これは中断されたCPU上で実行されます。これを実行するに戻ると状態が変わることがあります。 心配しないで、私は状態の宣言を見ていませんでした。 @ジョン・ボリンジャーが十分であると思われるもの。 – bhow

答えて

4

初期化要件は、Javaの正式な一部であるが欲しかった、次のとおりです。

ローカル変数またはブランクファイナルフィールドxのアクセスごとに、アクセスの前に必ずxを割り当てるか、コンパイル時にエラーが発生する必要があります。

JLS 8, chapter 16;元で強調)

JLSは

分析は、アカウントに文と 式の構造をとると言うことになります。式 の演算子!,&&,、およびブール値の定数 式の特別な処理も提供します。条件のブール演算子式の &&||、及び? :とブール値定数式の、値 の特別な処理を除い

をフロー分析に考慮されません。

明細用語ことを定義するようconditionが「定数式」ことはないfinalであるウェルこと

注(強調を追加しました)。仕様はthe specific rule for if statementsを与えることになります:

VV IFF if (e) SS後に割り当てられ、Vfalse [eがあると評価]ときe後に割り当てられた[解除]で[UN]は後に割り当てられている[UN]です。その後、あなたの特定のコードで

、:

int myVar; 

myVarは間違いなくここに割り当てられアンです。S、if文の本体は、無条件の割当を行うため

final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 

myVarは "Sの後に割り当て" されています。 myVartrueまたはfalseと評価されるかどうかにかかわらず、条件の評価後に割り当てられたではなく、です。したがって、メソッドのこの時点では、myVarが確実に割り当てられていません。

if (condition) { 

、何もこの時点では変更されています:その値が読まれてはならないので、myVarはまだ間違いなく、限りJLSルールが懸念しているとして割り当てられていません。それはOPがすでに質問の全体のポイントを約*理由コンパイラはある*であることから、ことを知っているかなり明白だ@imk

System.out.println("myVar = " + myVar); 
} 
関連する問題