2017-11-18 33 views
0

C++には、プリプロセッサディレクティブを値で置き換えるプリプロセッサがあります。今私の質問は:JAVA Javaのプリプロセッサのようなものがありますか? Javaでは、switch文のcaseの値はコンパイル時に評価されるものでなければならないことがわかります。たとえば:今すぐJAVA Javaにプリプロセッサのようなものがありますか?

int month = 5; 
switch(month) { 
    case 1: doSth() break; 
    ... 
    case month: doSth() break; 

この例では、私は、「ケースの月:」使用できない変数月の値は、実行時に評価されつつあるからです。しかし、私はこのように、最終的なキーワードを追加した場合:私は同じことを行うが、最終的なキーワードすべてがうまくいく持つ変数であれば

final month = 5; 

その後。 これはどういうものなのか、私に見せてもらえるこの "前処理された"コードについて説明することができますか?

+4

* JAVA Javaにはプリプロセッサのようなものがありますか?** **いいえ。** Javaプリプロセッサはありません。 'final'キーワードは、「変数」を定数にします。 –

+0

多くの場合、上記のようなユースケースは 'enums'でモデル化できます。 動的case/switch文が本当に必要な場合は、パターンライブラリまたはswitch文のラムダバージョンを使用してください。 –

+0

@Elliott Frischバイトコードのコンパイル時に、メモリに変数 "month"はなく、 "month"があった場所に "5"が置かれます。 – BoSsYyY

答えて

0

バイトコードのコンパイル時に、メモリに変数 "月"がなく、 "月"があった場所に "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つのケースがあるため、これはコンパイルできません。