java 开关箱中的OR运算符?

uurv41yg  于 2023-02-07  发布在  Java
关注(0)|答案(9)|浏览(145)

让我们看一个简单的开关案例,如下所示:

@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不接受此运算符的背景是什么?

zzlelutf

zzlelutf1#

伙计们都喜欢这样

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

这与在两个值之间使用OR运算符相同,因为在switch case中没有case运算符

ao218c7q

ao218c7q2#

开关箱不接受此运算符的背景是什么?
因为case需要常量表达式作为它的值。而且因为||表达式不是编译时常量,所以不允许使用。
摘自JLS第14.11节:
开关标签应具有以下语法:
开关标签:
case常量表达式:
案例枚举常量名称:
默认值:

引擎盖下:

从JVM规范第3.10节-编译开关中可以理解只允许带大小写的常量表达式背后的原因:
switch语句的编译使用tableswitchlookupswitch指令。当switch的大小写可以有效地表示为目标偏移量表的索引时,使用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指令将其索引到指令指针表中。

mutmk8jj

mutmk8jj3#

您不能使用||运算符。但您可以使用多个case值而不使用它们之间的break。然后程序将跳到相应的case,然后它将查找要执行的代码,直到找到"break"。结果,这些case将共享相同的代码。

switch(value) 
{ 
    case 0: 
    case 1: 
        // do stuff for if case 0 || case 1 
        break; 
    // other cases 
    default: 
        break; 
}
bt1cpqcv

bt1cpqcv4#

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

case 'E':
case 'e':
   System.exit(0);
   break;
rmbxnbpk

rmbxnbpk5#

开关与if-else-if不同。
当有一个表达式的计算结果为某个值并且该值可以是预定义值集中的一个值时,将使用开关。如果需要在运行时执行多个布尔/比较运算,则需要使用if-else-if。

mpbci0fu

mpbci0fu6#

Since Java 12及以上在以下情况下可以有多个值:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.someValue, R.id.someOtherValue:
            // do stuff
            break;
    }
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.someValue, R.id.someOtherValue -> {/* do stuff */}
    }
}
qf9go6mv

qf9go6mv7#

你还是可以这样做的。

switch (v.getId()) {
    case R.id.someValue: case R.id.someOtherValue:
        // do stuff
        break;
}
vxbzzdmp

vxbzzdmp8#

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;

    }
}

对于支持附件的语言,这很有效

mw3dktmi

mw3dktmi9#

在某些情况下会有所帮助。

switch(true){
 case a == b: break;
 case a == 2 || a == 3: break;
 default: break;
}

相关问题