web-dev-qa-db-fra.com

OR dans le boîtier de commutation?

Prenons un simple boîtier de commutation qui ressemble à:

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

Je me demande pourquoi il n'est pas permis d'utiliser le || opérateur? Comme

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

Le switch-case la construction est assez similaire à une if-else, vous pouvez cependant utiliser l'opérateur OR dans un if. Quels sont les arrière-plans d'un switch-case de ne pas accepter cet opérateur?

20
Droidman

Quels sont les antécédents d'un boîtier de commutation pour ne pas accepter cet opérateur?

Parce que case requiert une expression constante comme valeur. Et depuis un || l'expression n'est pas une constante de temps de compilation, elle n'est pas autorisée.

De JLS Section 14.11 :

L'étiquette du commutateur doit avoir la syntaxe suivante:

SwitchLabel:
case ConstantExpression:
case EnumConstantName:
défaut :


Sous la capuche:

La raison derrière permettant une expression juste constante avec des cas peut être comprise à partir de la JVM Spec Section 3.10 - Compilation des commutateurs :

La compilation des instructions switch utilise les instructions tableswitch et lookupswitch . L'instruction de commutateur de table est utilisée lorsque les cas du commutateur peuvent être efficacement représentés sous forme d'indices dans un tableau de décalages cibles. La cible par défaut du commutateur est utilisée si la valeur de l'expression du commutateur tombe en dehors de la plage des indices valides.

Ainsi, pour que le libellé de cas soit utilisé par tableswitch comme index dans la table des décalages cibles, la valeur du cas doit être connue au moment de la compilation. Cela n'est possible que si la valeur de casse est une expression constante. Et || expression sera évaluée au moment de l'exécution et la valeur ne sera disponible qu'à ce moment.

Dans la même section JVM, les éléments suivants switch-case:

switch (i) {
    case 0:  return  0;
    case 1:  return  1;
    case 2:  return  2;
    default: return -1;
}

est compilé pour:

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

Ainsi, si la valeur case n'est pas une expression constante, le compilateur ne pourra pas l'indexer dans la table des pointeurs d'instructions, en utilisant l'instruction tableswitch.

30
Rohit Jain

mec fais comme ça

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

Cela revient à utiliser l'opérateur OR entre deux valeurs. En raison de ce cas, l'opérateur n'est pas présent dans le cas de commutation

27
spt025

Vous ne pouvez pas utiliser || opérateurs entre 2 cas. Mais vous pouvez utiliser plusieurs valeurs de casse sans utiliser de pause entre elles. Le programme sautera alors dans le cas respectif et ensuite il recherchera le code à exécuter jusqu'à ce qu'il trouve une "rupture". Par conséquent, ces cas partageront le même code.

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

Le commutateur n'est pas identique à if-else-if.

Switch est utilisé lorsqu'il existe une expression qui est évaluée à une valeur et cette valeur peut être l'un d'un ensemble de valeurs prédéfinies. Si vous devez exécuter plusieurs opérations booléennes/comparaisons au moment de l'exécution, alors if-else-if doit être utilisé.

1
Prashant Bhate