final int a = 1;
final int b;
b = 2;
final int x = 0;
switch (x) {
case a:break; // ok
case b:break; // compiler error: Constant expression required
}
/* COMPILER RESULT:
constant expression required
case b:break;
^
1 error
*/
なぜこの種のエラーが発生するのですか?もし私がfinal int b = 2
、すべてが機能します。
b
が初期化されていない可能性があり、複数の値を割り当てることができます。あなたの例では明らかに初期化されていますが、おそらくコンパイラはそれを認識していません(そしてそれは認識できません)。想像してみてください:
final int b;
if (something) {
b = 1;
} else {
b = 2;
}
コンパイラーはswitch
に定数を必要としますが、b
の値は外部変数に依存します。
Switchステートメントの大文字と小文字は、コンパイル時の定数である必要があります。コマンド
final int b=2
コンパイル時に2
の値をb
に割り当てます。ただし、次のコマンドは、ランタイムで2
の値をb
に割り当てます。
final int b;
b = 2;
したがって、コンパイラは、switch
ステートメントのケースの1つで定数が見つからない場合、文句を言います。
値が割り当てられていない最後の変数は、空白変数と呼ばれます。空白のファイナルは1回だけ割り当てることができ、割り当てが発生したとき、またはプログラムで1回割り当てを解除する必要があります。
これを行うために、Javaコンパイラはフロー分析を実行して、空白の最終変数へのすべての割り当てについて、割り当ての前に変数が確実に割り当て解除されていることを確認します。そうでない場合、コンパイル時エラー発生します
そのため、コンパイラがスイッチコンストラクトをコンパイルすると、bの値がコンパイラに不明であるため、必要な定数式がスローされます。