【问题标题】:Constant expressions from an Enum枚举中的常量表达式
【发布时间】:2013-05-02 13:02:48
【问题描述】:

有没有办法将枚举转换为常量表达式? 我希望我的 switch 运算符在枚举的值中进行选择,但是我得到了一个编译错误“case 表达式必须是常量表达式”,所以我尝试在变量中声明它:

final int REG = MyEnum.REG.getIndex().intValue();

switch (service.getIndex()) {

case REG:

但我仍然遇到同样的错误。根据甲骨文的文档http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28

编译时常量表达式是表示值的表达式 原始类型或不突然完成的字符串 仅使用以下内容组成:

•原始类型的文字和字符串类型的文字

所以它不起作用,因为我没有使用文字。我想我必须将其声明为:

final int REG = 8;

但最好将它链接到枚举。有没有办法做到这一点?

编辑

原来我不需要使用任何最终变量。就这么简单:

switch (service) {

case REG:

直到我看到 Andrea 的评论,我才想到。感谢您的回答。

【问题讨论】:

  • 我假设service.getIndex() 返回Integer,对吧?您可以修改它以使其返回您的枚举吗?
  • 在 Java 1.6 之前,您不能在 switch-case 中使用 String,但您可以在 Java 7 中使用它。仅供参考

标签: java compile-time-constant


【解决方案1】:

如果可能,请修改您的 getIndex() 方法,使其返回枚举而不是整数。如果这不可能,您需要将索引映射到枚举元素:

给定以下枚举:

public enum Index {
   ONE,
   TWO,
   THREE
}

您可以使用将索引映射到枚举元素

Index.values()[index]

根据您的方法Integer getIndex(),您可以执行类似的操作

switch(Index.values()[getIndex()])
    case ONE : ... 
       break;

    case TWO : ...
       break;

    case THREE : ...
       break;
}

请注意,如果您尝试访问枚举中大于枚举元素数量的索引,这可能会引发ArrayIndexOutOfBoundsException(例如,在上面的示例中,如果getIndex() 返回的值> 2)。


我会将表达式Index.values()[getIndex()] 封装到一个像valueOf(int index) 这样的枚举方法中,类似于默认的valueOf(String s)。然后,您还可以在那里处理有效的数组索引检查(例如,如果索引超出范围,则返回一个特殊的枚举值)。同样,您还可以转换具有特殊含义的离散值:

public enum Index {
   ZERO,
   ONE,
   TWO,
   THREE,
   REG,
   INVALID;


   public static Index valueOf(int index) {

       if (index == 8) {
          return REG;
       }

       if (index >= values().length) {
          return INVALID;
       }

       return values()[index];
   }
}

这只是一个示例 - 在任何情况下,它通常取决于您从 getIndex() 方法获得的值的范围,以及您希望如何将它们映射到枚举元素。

你可以像这样使用它

switch(Index.valueOf(service.getIndex())) {
   case ZERO : ... break;
   ...
   case REG : ... break;
   ...
}

另请参阅 Cast Int to enum in Java 以获取更多信息(尤其是提示 values() 是一项昂贵的操作,因为它需要在每次调用时返回数组的副本)。

【讨论】:

    【解决方案2】:

    如果你想将特定数值分配给枚举常量,请像这样

    enum MyReg {
        REG(8), OTHER(13);
    
        public final int value;
        MyReg(int value) {
            this.value=value;
        }
    }
    

    然后你像这样使用它:

    class Test { 
        public static void main(String[] args) {
            MyReg reg = MyReg.REG;
            switch (reg) {
            case OTHER:
                System.out.println(reg.value);
                break;
            case REG:
                System.out.println(reg.value);
                break;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2019-06-11
      相关资源
      最近更新 更多