48

次のような単純なスイッチケースを考えてみましょう:

@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とよく似ていますが、OR 演算子を使用できます。このオペレーターを受け入れない理由は何ですか?if-elseifswitch-case

4

6 に答える 6

86

男はこのようにします

    case R.id.someValue :
    case R.id.someOtherValue :
       //do stuff

これは、2 つの値の間で OR 演算子を使用するのと同じです。このケースのため、スイッチ ケースには演算子がありません。

于 2013-08-23T22:45:27.680 に答える
54

switch-case がこの演算子を受け入れない背景は何ですか?

case値として定数式が必要なためです。また、||式はコンパイル時の定数ではないため、使用できません。

JLSセクション14.11から:

スイッチ ラベルの構文は次のとおりです。

SwitchLabel:
case 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

于 2013-08-23T22:42:43.040 に答える