次のような単純なスイッチケースを見てみましょう。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue :
case R.id.someOtherValue:
// do stuff
break;
}
}
||
演算子を使用できないのはなぜですか?いいね
switch (v.getId()) {
case R.id.someValue || R.id.someOtherValue:
// do stuff
break;
}
switch-case
コンストラクトはif-else
ステートメントに非常に似ていますが、if
でOR演算子を使用できます。 switch-case
はこの演算子を受け入れませんか?
この演算子を受け入れないスイッチケースの背景は何ですか?
case
は値として定数式を必要とするためです。 ||
expressionはコンパイル時定数ではないため、許可されていません。
JLSセクション14.11 から:
スイッチラベルの構文は次のとおりです。
SwitchLabel:
ConstantExpressionの場合:
case EnumConstantName:
デフォルト :
ケースで定数式のみを許可する背後にある理由は、 JVM Spec Section 3.10-Compiling Switches から理解できます。
Switchステートメントのコンパイルでは、tableswitchおよびlookupswitch命令を使用します。 tableswitch命令は、スイッチのケースをターゲットオフセットのテーブルへのインデックスとして効率的に表すことができる場合に使用されます。スイッチの式の値が有効なインデックスの範囲外にある場合、スイッチのデフォルトのターゲットが使用されます。
したがって、tableswitch
がターゲットオフセットのテーブルへのインデックスとして使用するケースラベルの場合、ケースの値はコンパイル時にわかっている必要があります。これは、ケース値が定数式である場合にのみ可能です。そして、||
式は実行時に評価され、値はその時点でのみ使用可能になります。
同じJVMセクションから、次のswitch-case
:
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
にコンパイルされます:
0 iload_1 // Push local variable 1 (argument i)
1 tableswitch 0 to 2: // Valid indices are 0 through 2 (NOTICE This instruction?)
0: 28 // If i is 0, continue at 28
1: 30 // If i is 1, continue at 30
2: 32 // If i is 2, continue at 32
default:34 // Otherwise, continue at 34
28 iconst_0 // i was 0; Push int constant 0...
29 ireturn // ...and return it
30 iconst_1 // i was 1; Push int constant 1...
31 ireturn // ...and return it
32 iconst_2 // i was 2; Push int constant 2...
33 ireturn // ...and return it
34 iconst_m1 // otherwise Push int constant -1...
35 ireturn // ...and return it
そのため、case
値が定数式でない場合、コンパイラはtableswitch
命令を使用して、命令ポインターのテーブルにインデックスを付けることができません。
男はこのようにします
case R.id.someValue :
case R.id.someOtherValue :
//do stuff
これは、2つの値の間にOR演算子を使用するのと同じです
||は使用できません2つのケースの間にある演算子。ただし、それらの間に区切りを使用せずに複数のケース値を使用できます。その後、プログラムはそれぞれのケースにジャンプし、「ブレーク」が見つかるまで実行するコードを探します。その結果、これらのケースは同じコードを共有します。
switch(value)
{
case 0:
case 1:
// do stuff for if case 0 || case 1
break;
// other cases
default:
break;
}
スイッチはif-else-ifと同じではありません。
スイッチは、値に評価される式が1つあり、その値が事前定義された値のセットの1つである場合に使用されます。実行時に複数のブール演算/比較演算を実行する必要がある場合、if-else-ifを使用する必要があります。