java - A Switch Java 问题 : case expressions must be constant expressions

标签 java android switch-statement

我的 switch/case 语句有问题。错误说:“案例表达式必须是常量表达式”。我理解错误,我可以使用 If 解决它,但有人可以告诉我为什么 case 表达式必须在 switch/case 中保持不变。 我的错误代码示例:

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

谢谢你的解释!!

最佳答案

所以可以在编译阶段进行评估(静态检查)

见:http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11 switch 的正式定义。

此外,它还可以帮助您更好地理解 switch 是如何转换为字节码的:

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

编译后:

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

}

看到标记为1的那一行:

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

它评估值并转到其他行。例如,如果值为 9,它将跳转到指令 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

然后跳转到指令 58:

   58:  return

如果动态评估,这一切都是不可能的。这就是为什么。

关于java - A Switch Java 问题 : case expressions must be constant expressions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4742660/

相关文章:

Java、线程和优先级

ios - Unity 窗口 + 原生 iOS 窗口在同一个 App 上?

java - 什么是链式矩阵乘法?

java - 如何使受管实体具有上下文感知能力?

java - 尝试制作一个添加变量的简单应用程序,遇到一些问题

java - 为什么 'BackgroundFetchHeadlessTask.java' 在 ionic 中不起作用?

java - 为什么 editText 中的文本没有水平居中?

c - 多个案例的 switch 语句

android - 如何检测开关何时滑动,而不是单击

java - 使用 ImageView 填充数组适配器