开关盒中的 OR 运算符?

新手上路,请多包涵

让我们看一个简单的 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 结构与 if-else 语句非常相似,但是您可以在 if 中使用 OR 运算符。 switch-case 不接受这个运营商的背景是什么?

原文由 Droidman 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 540
2 个回答

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

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

JLS 第 14.11 节

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

开关标签:

案例常量表达式:

案例 EnumConstantName :

默认 :


引擎盖下:

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

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

因此,对于 tableswitch 使用的 case 标签作为目标偏移表的索引,case 的值应该在编译时知道。这只有在 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 指令将其索引到指令指针表中。

原文由 Rohit Jain 发布,翻译遵循 CC BY-SA 3.0 许可协议

伙计喜欢这个

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

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

原文由 spt025 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题