48

让我们看一个简单的 switch-case,如下所示:

@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非常相似,但是您可以在 an中使用 OR 运算符。不接受这个运营商的背景是什么?if-elseifswitch-case

4

6 回答 6

86

伙计喜欢这样

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

这与在两个值之间使用 OR 运算符相同因为这种情况运算符在 switch case 中不存在

于 2013-08-23T22:45:27.680 回答
54

switch-case 不接受此运算符的背景是什么?

因为case需要常量表达式作为它的值。并且由于||表达式不是编译时常量,因此是不允许的。

JLS 第 14.11 节

开关标签应具有以下语法:

SwitchLabel:
案例ConstantExpression:
案例EnumConstantName:
默认:


引擎盖下:

可以从JVM Spec 第 3.10 节 - 编译开关中了解仅允许使用 case 进行常量表达式的原因:

switch 语句的编译使用tableswitchlookupswitch指令。当切换的情况可以有效地表示为目标偏移表中的索引时,使用 tableswitch 指令。如果 switch 表达式的值超出有效索引的范围,则使用 switch 的默认目标。

因此,对于要用作tableswitch目标偏移表的索引的案例标签,案例的值应该在编译时已知。这只有在 case 值是一个常量表达式时才有可能。并且||表达式将在运行时评估,并且该值仅在那时可用。

从同一 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 回答
40

你不能使用 || 运算符介于 2 种情况之间。但是您可以使用多个 case 值,而无需在它们之间使用中断。然后程序将跳转到相应的案例,然后它将寻找要执行的代码,直到找到“中断”。因此,这些案例将共享相同的代码。

switch(value) 
{ 
    case 0: 
    case 1: 
        // do stuff for if case 0 || case 1 
        break; 
    // other cases 
    default: 
        break; 
}
于 2018-08-26T05:54:17.587 回答
1

Switch 与 if-else-if 不同。

当有一个表达式被评估为一个值并且该值可以是预定义的一组值之一时,使用 Switch。如果您需要在运行时执行多个布尔/比较操作,则需要使用 if-else-if。

于 2013-08-23T23:08:13.693 回答
1

我不知道最好的方法,但我这样做

case 'E':
case 'e':
   System.exit(0);
   break;
于 2021-04-21T04:29:09.123 回答
-1
foreach (array('one', 'two', 'three') as $v) {
    switch ($v) {
        case (function ($v) {
            if ($v == 'two') return $v;
            return 'one';
        })($v):
            echo "$v min \n";
            break;


    }
}

这适用于支持外壳的语言

于 2017-11-18T13:14:48.860 回答