2017-11-10 2 views
1

これは、コンパイラがローカル変数kのInitializerエラーをチェックする場合の変数の明確な割り当てを参照しています。どんなflag変数の値は、k変数の値が割り当てられることになる以下のシナリオで変数の確定的な割り当て

k needs to be initialized.

void flow(boolean flag) { 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 

コードのこの部分は、コンパイルエラーをスローしません。ここでコンパイルエラーが正当化されていますか?

+3

コンパイラは、「else」を使用しないと両方のフラグ条件をチェックしたことを知るのに十分スマートではありません。 'else'を使います。 –

+3

もっと良い質問は、このコードは正当なものですか?ブール値の両側を明示的にチェックするのはなぜですか? – shmosel

+2

はるかに良いバージョンは 'final int k = flag? 3:4; '5行ではなく1行で、分かりやすいように、変数' k'は不変です。 – vanje

答えて

2

これは、コンパイラが最終的ではないフィールドの値をすべてチェックしないためです(ここではflag)。

コンパイラはコンパイル時の定数を解析し、ローカル変数が初期化されるかどうかを確認することしかできません。 Java言語仕様では、この上の

より:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html

それがためにコンパイラエラーをスロー、コンパイラはフラグの値を知っているにもかかわらず、ここで...

を同じ方法の2つのより多くのバリエーションを考えてみましょう変数k。ここ

void flow() { 
    boolean flag = false; 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 

フラグは、コンパイル時定数であるように、コンパイラは、変数kと従ってNOコンパイルエラーの値を算出することができます。

void flow() { 
    final boolean flag = false; 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 
+0

これは私の疑いを明確にします。コンパイル時定数は、私が主に探していたものでした。 – Ronald

2

はい、変数kは状態に関係なく初期化されます。しかし、2つの条件が互いに関連していないため、コンパイラは、kが時刻コントロールによってprintlnメソッド呼び出しに到達することによって初期化されたことを保証できません。私が想定しています

あなたが当面の問題への修正を知っているが、それはケースがない場合は、あなただけの最初の文ifelseブロックをチェーン2番目ifステートメントを削除する必要があります。

+0

これは私がチュートリアルを読んでいる間に出会ったコードです、私はソリューションが時間定数をコンパイルしていると思います。はい、私はこのコードの修正を知っています:) thanks – Ronald

関連する問題