switch 语句中用于案例选择的常量映射?
Constant Map for case selection in switch statement?
有没有办法定义常量 Map
以便在 switch 语句中使用?我对来自 here, here 和其他人的静态地图的所有试验均未成功。为什么 Map 不是常量?
对于行 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");
}
}
}
否,因为 switch 语句中的 case 标签必须是常量表达式或枚举数。
对您的地图的引用是 final
,并且您的地图不可修改。但后者在运行时间强制执行。编译器不会将该对象视为常量。
来自Java Language Specification, 14.11: The switch statement:
SwitchLabel:
case ConstantExpression :
case EnumConstantName :
default :
常量表达式只能由原始字面量和字符串文字、某些没有副作用的运算符、常量变量和一些可以在编译时计算的其他组件组成。 (常量变量是已初始化为常量表达式的 final
原始类型或字符串类型的变量。)更多详细信息位于 15.28: Constant expressions.
我不知道你的用例,但你可以使用参数化枚举来代替不可修改的映射:
>> 当:
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;
}
}
>>然后:
...
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");
}
...
有没有办法定义常量 Map
以便在 switch 语句中使用?我对来自 here, here 和其他人的静态地图的所有试验均未成功。为什么 Map 不是常量?
对于行 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");
}
}
}
否,因为 switch 语句中的 case 标签必须是常量表达式或枚举数。
对您的地图的引用是 final
,并且您的地图不可修改。但后者在运行时间强制执行。编译器不会将该对象视为常量。
来自Java Language Specification, 14.11: The switch statement:
SwitchLabel:
case ConstantExpression :
case EnumConstantName :
default :
常量表达式只能由原始字面量和字符串文字、某些没有副作用的运算符、常量变量和一些可以在编译时计算的其他组件组成。 (常量变量是已初始化为常量表达式的 final
原始类型或字符串类型的变量。)更多详细信息位于 15.28: Constant expressions.
我不知道你的用例,但你可以使用参数化枚举来代替不可修改的映射:
>> 当:
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;
}
}
>>然后:
...
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");
}
...