バイトコードのコンパイル時に、メモリに変数 "月"がなく、 "月"があった場所に "5"が配置されていますか?
はい、いいえ。何が起こっているのは、final
キーワードは、変数が変更できないことをコンパイラに知らせるため、定数として扱うことができ、定数が必要な場所で使用できます。これがカバーの下でどのように起こるかは重要ではありませんが、実際には一定の値に置き換えられます。
今度は、あなたのコードを考えてみましょう:
int month = 5;
switch(month) {
case 1: doSth() break;
...
case month: doSth() break; // compilation error
スイッチ変数はあなたの例1と同じであるので、何かない右ここにあります。これを通る唯一の可能なパスはmonth
ケースなので、他のすべてのケースはデッドコードです。たぶん、あなたは意味:
int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Still a compilation error
これは少し良く見えますがmonthOfInterest
は「定数式」ではありませんので、コンパイルされません。ここであなたの元の質問に行きます。大文字小文字のセレクタは、コンパイル時に評価できる数値リテラルまたは式のいずれかでなければなりません。 monthOfInterest
が一定5
によって置き換えられたかのように、この「振る舞い」
final int monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // This is valid code
:だから私たちは、これを変更します。
final int monthOfInterest;
...
monthOfInterest = 5;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops, compilation error again
変数final
を宣言し、後でそれを初期化するために、完全に合法である:これは同じではないことに注意してください。コンパイラは値を1回だけ確実に設定しますが、この場合はmonthOfInterest
はもはや定数式ではなくなり、このコードはコンパイルされません。
最後のメモ。次のように考慮してください。
final int monthOfInterest = 1;
switch(month) {
case 1: doSth() break;
...
case monthOfInterest: doSth() break; // Oops again, different compilation problem
同じ値を持つ2つのケースがあるため、これはコンパイルできません。
* JAVA Javaにはプリプロセッサのようなものがありますか?** **いいえ。** Javaプリプロセッサはありません。 'final'キーワードは、「変数」を定数にします。 –
多くの場合、上記のようなユースケースは 'enums'でモデル化できます。 動的case/switch文が本当に必要な場合は、パターンライブラリまたはswitch文のラムダバージョンを使用してください。 –
@Elliott Frischバイトコードのコンパイル時に、メモリに変数 "month"はなく、 "month"があった場所に "5"が置かれます。 – BoSsYyY