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?
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 :
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
.
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
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;
}
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é.