是否可以在java switch / case语句中使用类名?

时间:2016-01-05 13:36:24

标签: java switch-statement const final class-names

我想使用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

3 个答案:

答案 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;
}