我想使用java switch
语句,它使用class
名称作为case
常量。有可能吗?或者我是否必须复制类名?
由于编译器错误:
,以下代码无效案例表达式必须是常量表达式
String tableName = "MyClass1";
...
switch (tableName) {
case MyClass1.class.getSimpleName():
return 1;
case MyClass2.class.getSimpleName():
return 2;
default:
return Integer.MAX_VALUE;
}
以下是该问题的在线演示(openjdk 1.8.0_45
):http://goo.gl/KvsR6u
答案 0 :(得分:9)
编译器错误已经说明了。案例标签必须是常量表达式,类文字和在它们上调用getSimpleName()
的结果都不是常量表达式。
一个有效的解决方案是:
String tableName = "MyClass1";
...
switch (tableName) {
case "MyClass1":
return 1;
case "MyClass2":
return 2;
default:
return Integer.MAX_VALUE;
}
表达式MyClass1.class.getSimpleName()
并不比"MyClass1"
简单,但是,当然,不会有任何编译时检查名称是否与现有类匹配,重构工具或混淆器是否不会注意到类MyClass1
与字符串文字"MyClass1"
之间的关系。
没有解决方法。你唯一可以做的就是减少问题,就是在相关类中声明密钥以记录关系,例如。
class MyClass1 {
static final String IDENTIFIER = "MyClass1";
...
}
class MyClass2 {
static final String IDENTIFIER = "MyClass2";
...
}
...
String tableName = MyClass1.IDENTIFIER;
...
switch (tableName) {
case MyClass1.IDENTIFIER:
return 1;
case MyClass2.IDENTIFIER:
return 2;
default:
return Integer.MAX_VALUE;
}
这记录了与读者的关系,但工具仍然无法确保实际的字符串内容与类名匹配。但是,根据您想要实现的目标,现在可能变得无关紧要,字符串内容是否与类名匹配...
答案 1 :(得分:8)
为什么不将映射存储在地图中而不是使用开关?
创建String to Integer的映射,并将所有类名映射到它们的返回值。
在请求中,如果条目不存在,则返回默认值。否则,返回地图中的值。
答案 2 :(得分:2)
而不是Switch..case为什么不使用If..Else。应该在所有版本的java中工作,直到我知道。
if (tableName.equals(MyClass1.class.getSimpleName())) {
return 1;
} else if (tableName.equals(MyClass2.class.getSimpleName())) {
return 2;
} else {
return Integer.MAX_VALUE;
}