28

最終変数とコンパイル時定数の違いは何ですか?

次のコードを検討してください

final int a = 5;
final int b;
b=6;
int x=0;
switch(x)
{
     case a: //no error
     case b: //compiler error
}

これは何を意味するのでしょうか?final 変数にはいつ、どのように値が割り当てられますか? 実行時に何が起こり、コンパイル時に何が起こるのでしょうか? switch にコンパイル時定数を与える必要があるのはなぜですか? コンパイル時定数を必要とするJavaの他の構造は何ですか?

4

5 に答える 5

28

問題は、すべてのcase:ステートメントがコンパイル時に究極でなければならないということです。あなたの最初のステートメントは究極です。a100%の場合は。以外の値にはなりません5

final int a = 5;

ただし、これは保証されていませb。周りにifステートメントがあるとしたらどうでしょうbか?

final int b;
if(something())
   b=6;
else
   b=5;
于 2013-03-09T10:52:23.733 に答える
7

これは何を意味するのでしょうか?

これは、「b」がコンパイル時定数式ではなく、JLSがそれを要求することを意味します。

最終変数にはいつ、どのように値が割り当てられますか?

正式には、代入ステートメントまたは初期化子が実行されるとき。

ただし、実際には、final宣言がコンパイル時定数を宣言している場合、式はコンパイル時に評価され、その値はコードに組み込まれます。

実行時に何が起こり、コンパイル時に何が起こりますか?

上記を参照。

スイッチにコンパイル時定数を与える必要があるのはなぜですか?

JLSがそれを必要とするからです。

バイトコードコンパイラは、switchステートメントが整形式であることを確認する必要があります。つまり、スイッチ定数の値が衝突しないということです。また、JITコンパイラは、スイッチ定数の実際の値に最適化されたコードを生成できます。

Javaの他のどの構造がコンパイル時定数を要求しますか?

頭のてっぺんから、私が考えることができるものはありません。

于 2013-03-09T10:54:04.703 に答える
3

コンパイラの観点からは、初期化されていない可能性のある変数 b を使用しようとしています。switch ステートメントはJVM バイトコード テーブルスイッチまたはルックアップスイッチにコンパイルされます。これには、case ステートメントで使用される値がコンパイル時の定数と一意の両方である必要があります。

final int a = 4; // compiler is sure a is initialized
final int b;// variable b is not guranted to be assigned

たとえば、このステートメントは最終的に b を初期化しますが、コンパイラはそれを検出できません。

if (a < 4) b= 10;
if (a >= 4) b = 8
于 2013-03-09T11:00:42.427 に答える
2

switch ステートメントには定数が必要です。最終変数は初期化が遅れる可能性があり、コンパイラは b が case 分岐に値を持つことを判断できません。

于 2013-03-09T10:34:18.113 に答える
2

final int b;一度割り当てることができ、値は不明です。これは、条件に応じて実行時に決定されます。これが理由です。final 変数であっても、COMPILE TIME 定数ではありませんRUN TIME定数になり、場合によってはコンパイル時定数が必要になります。

于 2013-03-09T11:02:19.673 に答える