Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Switch Java problem : case expressions must be constant expressions

I having a problem in my switch/case statement. The error says : "Case expressions must be constant expressions". I understand the error and I can resolve it using If but can someone tells me why the case expression must be constant in a switch/case. A code example of my error :

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); } 

Thx for your explanation !!

like image 734
Dimitri Avatar asked Jan 20 '11 01:01

Dimitri


People also ask

Can we use expression in switch case in Java?

The switch case in Java works like an if-else ladder, i.e., multiple conditions can be checked at once. Switch is provided with an expression that can be a constant or literal expression that can be evaluated. The value of the expression is matched with each test case till a match is found.

Can we use constants in switch case?

The constant-expression for a case must be the same data type as the variable in the switch, and it must be a constant or a literal. When the variable being switched on is equal to a case, the statements following that case will execute until a break statement is reached.

What are constant expressions in Java?

A constant expression is an expression that yields a primitive type or a String, and whose value can be evaluated at compile time to a literal. The expression must evaluate without throwing an exception, and it must be composed of only the following: Primitive and String literals.

Which datatypes are allowed in case expression of switch?

A switch works with the byte , short , char , and int primitive data types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character , Byte , Short , and Integer (discussed in Numbers and Strings).


1 Answers

So it can be evaluated during the compilation phase ( statically check )

See: http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 for a formal definition of the switch.

Additionally it may help you to understand better how that switch is transformed into 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;     }   } } 

And after compiling:

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  } 

See that line marked as 1:

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

It evaluates the value and goes to some other line. For instance if value is 9 it will jump to 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 

Which in turn jumps to instruction 58 :

   58:  return 

All this wouldn't be possible if it was evaluated dynamically. That's why.

like image 60
OscarRyz Avatar answered Sep 24 '22 00:09

OscarRyz