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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34613052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 23:07:07  来源:igfitidea点击:

Is it possible use a class name in java switch/case statement?

javaswitch-statementconstfinalclass-names

提问by dedek

I would like to use a java switchstatement, which uses classnames as caseconstants. Is it possible somehow? Or do I have to duplicate the class names?

我想使用一个 javaswitch语句,它使用class名称作为case常量。有可能吗?还是我必须复制类名?

Following code does not work because of compiler error:

由于编译器错误,以下代码不起作用:

case expressions must be constant expressions

case 表达式必须是常量表达式

String tableName = "MyClass1";

...

switch (tableName) {
case MyClass1.class.getSimpleName():
    return 1;
case MyClass2.class.getSimpleName():
    return 2;
default:
    return Integer.MAX_VALUE;
}

Here is a online demonstration of the issue (openjdk 1.8.0_45): http://goo.gl/KvsR6u

这是该问题的在线演示 ( openjdk 1.8.0_45):http: //goo.gl/KvsR6u

采纳答案by Holger

The compiler error already says it. The case labels must be constant expressions and neither, class literals nor the result of invoking getSimpleName()on them, are constant expressions.

编译器错误已经说明了。case 标签必须是常量表达式,类文字和调用getSimpleName()它们的结果都不是常量表达式。

A working solution would be:

一个可行的解决方案是:

String tableName = "MyClass1";
...
switch (tableName) {
    case "MyClass1":
        return 1;
    case "MyClass2":
        return 2;
    default:
        return Integer.MAX_VALUE;
}

The expression MyClass1.class.getSimpleName()is not simpler than "MyClass1", but, of course, there won't be any compile-time check whether the names match existing classes and refactoring tools or obfuscators don't notice the relationship between the class MyClass1and the string literal "MyClass1".

表达式MyClass1.class.getSimpleName()并不比 简单"MyClass1",但是,当然,不会有任何编译时检查名称是否与现有类匹配,重构工具或混淆器不会注意到类MyClass1和字符串字面量之间的关系"MyClass1"

There is no solution to that. The only thing you can do to reduce the problem, is to declare the keys within the associated class to document a relationship, e.g.

没有解决办法。唯一可以减少问题的方法是在关联类中声明键以记录关系,例如

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

This documents the relationship to the reader, but tools still won't ensure that the actual string contents matches the class name. However, depending on what you want to achieve, it might become irrelevant now, whether the string contents matches the class name…

这记录了与读者的关系,但工具仍然无法确保实际的字符串内容与类名匹配。但是,取决于您要实现的目标,现在可能变得无关紧要,字符串内容是否与类名匹配......

回答by Sam Sun

Instead of using a switch, why not store the mappings in a map?

与其使用开关,为什么不将映射存储在映射中?

Create a map of String to Integer, and map all the class names to their return value.

创建一个 String 到 Integer 的映射,并将所有类名映射到它们的返回值。

On a request, if the entry does not exist, return the default value. Otherwise, return the value in the map.

在请求中,如果条目不存在,则返回默认值。否则,返回地图中的值。

回答by Rajen Raiyarela

Instead of Switch..case why don't you use If..Else. Should work in all versions of java till i know.

而不是 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;
}