web-dev-qa-db-fra.com

Un commutateur Java: les expressions de casse doivent être des expressions constantes

J'ai un problème dans ma déclaration switch/case. L'erreur indique: "Les expressions de cas doivent être des expressions constantes". Je comprends l'erreur et je peux la résoudre en utilisant If mais quelqu'un peut-il me dire pourquoi l'expression de la casse doit être constante dans un commutateur/cas. Un exemple de code de mon erreur:

public boolean onOptionsItemSelected(MenuItem item) {
    int idDirectory = ((MenuItem) findViewById(R.id.createDirectory)).getItemId();
    int idSuppression = ((MenuItem) findViewById(R.id.recycleTrash)).getItemId();
    int idSeeTrash = ((MenuItem) findViewById(R.id.seeTrash)).getItemId();

    switch (item.getItemId()) {
    case idDirectory:
        createDirectory(currentDirectory);
        break;
    case idSuppression:
        recycleTrash();
        break;
    case idSeeTrash:
        seeTrash();
        break;
    }

    return super.onOptionsItemSelected(item);
}

Merci pour votre explication !!

26
Dimitri

Il peut donc être évalué lors de la phase de compilation (vérification statique)

Voir: http://docs.Oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 pour une définition formelle de switch .

De plus, cela peut vous aider à mieux comprendre comment ce switch est transformé en bytecode:

class Switch {
  void x(int n ) {
    switch( n ) {
      case 1: System.out.println("one"); break;
      case 9: System.out.println("nine"); break;
      default:  System.out.println("nothing"); break;
    }
  }
}

Et après avoir compilé:

C:\>javap -c Switch
Compiled from "Switch.Java"
class Switch extends Java.lang.Object{
Switch();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method Java/lang/Object."<init>":()V
   4:   return

void x(int);
  Code:
   0:   iload_1
   1:   lookupswitch{ //2
                1: 28;
                9: 39;
                default: 50 }
   28:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   31:  ldc     #3; //String one
   33:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   36:  goto    58
   39:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   42:  ldc     #5; //String nine
   44:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   47:  goto    58
   50:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   53:  ldc     #6; //String nothing
   55:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   58:  return

}

Voir cette ligne marquée comme 1:

 1:   lookupswitch{ //2
            1: 28;
            9: 39;
            default: 50 }

Il évalue la valeur et passe à une autre ligne. Par exemple, si la valeur est 9 il passera à l'instruction 39:

   39:  getstatic       #2; //Field Java/lang/System.out:Ljava/io/PrintStream;
   42:  ldc     #5; //String nine
   44:  invokevirtual   #4; //Method Java/io/PrintStream.println:(Ljava/lang/String;)V
   47:  goto    58

Qui à son tour saute à l'instruction 58:

   58:  return

Tout cela ne serait pas possible s'il était évalué dynamiquement. C'est pourquoi.

54
OscarRyz

dans Eclipse IDE est simple, dans la phrase de commutation CTRL + 1 et convertit la phrase de commutation - phrase if-else http://tools.Android.com/tips/non-constant- champs

13
ingyesid

idDirectory et les autres doivent être une constante et non une variable déclarée. Switch ne fonctionnera pas dans ce cas, vous devez passer à if-else construire.

EDIT Je vois ce que OP voulait dire. Voilà comment fonctionne switch en Java.

3
fastcodejava