在switch语句中选择case的常量映射?

时间:2015-11-05 16:38:42

标签: java dictionary switch-statement

有没有办法为switch语句中的用法定义常量Map?我使用herehere和其他人的静态地图进行的所有试验均未成功。为什么地图不是常数?

对于专栏case (kws.get(KEYWORD_NAME)):,我总是收到constant string expression required错误。

public class Demo {

  public static final String KEYWORD_NAME = "Name";
  public static final String KEYWORD_TYPE = "Type";

  private static final Map<String, String> kws = Collections.unmodifiableMap(
  new HashMap<String, String>() {{
    put(KEYWORD_NAME, KEYWORD_NAME.toLowerCase());
    put(KEYWORD_TYPE, KEYWORD_TYPE.toLowerCase());
  }});

  public static void parse(String kw){
    switch(kw){
      case (kws.get(KEYWORD_NAME)):
        System.out.println("Test");
        break;
    default:
      System.out.println("Unknown");
    }
  }
}

2 个答案:

答案 0 :(得分:7)

不,因为switch语句中的case标签必须是常量表达式或枚举器。

对地图的引用为final,您的地图无法修改。但后者是在运行时强制实施的。编译器不会将对象视为常量。

来自Java Language Specification, 14.11: The switch statement

SwitchLabel:
case ConstantExpression : 
case EnumConstantName : 
default :

常量表达式只能由原语和字符串文字,没有副作用的某些运算符,常量变量以及可以在编译时计算的一些其他组件组成。 (常量变量是基元或字符串类型的final变量,已初始化为常量表达式。)更多详细信息位于15.28: Constant expressions

答案 1 :(得分:0)

我不知道你的用例,但是你可以使用参数化枚举来代替使用不可修改的地图:

&GT;&GT;当:

public enum Demo {
     NAME("Name"),
     TYPE("Type"),
     NOT_SUPPORTED("");

    private String code;
    private static final Map<String, Demo> CODE_VALUE_MAP = new LinkedHashMap<>();

    // -- static
    static {
        for (Demo demo : Demo.values()) {
            CODE_VALUE_MAP.put(demo.getCode(), demo );
        }
     }

   public static Demo forCode(@NotNull String code) {
        if (code!= null) {
            return CODE_VALUE_MAP.getOrDefault(code.toUpperCase(), NOT_SUPPORTED);
           }
           return NOT_SUPPORTED;
       }    
   }

   // -- constructor
   Demo(String code) {
       this.code= code;
   }

   // -- public methods
   public String getCode() {
       return code;
   }
}

&GT;&gt;下面:

...
public static void parse(String kw){
 Demo demo = Demo.forCode(kw);
 switch(demo){
  case NAME:
    System.out.println("Test");
    break;
default:
  System.out.println("Unknown");
}
...