当前位置: 首页 > 面试题库 >

Switch Java问题:case表达式必须是常量表达式

东郭元魁
2023-03-14
问题内容

我在switch / case语句中遇到问题。该错误显示:“
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 }

它评估该值并转到其他行。例如,如果值为value 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

如果它是动态评估的,那么所有这些都是不可能的。这就是为什么。



 类似资料:
  • 问题内容: 我的转换案例声明昨天运行良好。但是,当我今天早些时候运行代码时,eclipse给我一个错误,强调了红色的case语句,并说:case表达式必须是常量表达式,它是常量,我不知道发生了什么。这是我的代码如下: 所有R.id.int都用红色下划线。 问题答案: 在常规的Android项目中,资源R类中的常量声明如下: 但是,从ADT 14开始,在图书馆项目中,它们将这样声明: 换句话说,常数

  • 问题内容: Eclipse不断给我错误: 但是我绝对可以给注解一个常量。 如果我将其更改为 很高兴,但我不必这样做。有谁知道为什么我的MIN_YEAR常量使用评估表达式而不是纯数字声明时不被视为常量? 问题答案: 表达方式 将仅在运行时确定,但是 是在编译时确定的,因此允许使用,因为注释中的值应在编译时而不是运行时解析。

  • 常量表达式机制是为了: 提供一种更加通用的常量表达式 允许用户自定义的类型成为常量表达式 提供了一种保证在编译期完成初始化的方法(可以在编译时期执行某些函数调用) 考虑下面这段代码: enum Flags { good=0, fail=1, bad=2, eof=4 }; constexpr int operator|(Flags f1, Flags f2) { return Flags(int(

  • 本文向大家介绍常见的正则表达式问题,包括了常见的正则表达式问题的使用技巧和注意事项,需要的朋友参考一下 正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”)。模式描述在搜索文本时要匹配的一个或多个字符串。 关于^开始和$结束的问题注意 \b匹配一个单词边界, ?: ?= ?! 这四个不加^和$,其他都加^和$。 关于|的理解 1:/^a|zood$/

  • 问题内容: 我在代码中使用注释,并且尝试使用在运行时确定的值。 我将列表定义为(lst),并将一些元素添加到此列表中。 使用时,出现编译错误: 这个问题有什么解决方案? 问题答案: 注释的值必须是一个编译时间常数,因此没有简单的方法可以完成您想做的事情。 另请参见此处:如何通过Constantjava为注释提供值 如果在尝试运行程序之前知道该值,则可以使用一些编译时工具(ant,maven?)进行

  • 本文向大家介绍Ruby中case表达式详解,包括了Ruby中case表达式详解的使用技巧和注意事项,需要的朋友参考一下 Ruby的case表达式有两种形式: 第一种形式接近于一组连续的if语句:它让你列出一组条件,并执行第一个为真的条件表达式所对应的语句。 第二种形式,在case语句的顶部指定一个目标,而每个when从句列出一个或者多个比较条件 和if一样,case返回执行的最后一个表达式的值;而