有什么方法可以在 Java 8 中将 Switch 语句的 Case 标签检索为集合?

Is there any way to retrieve the Case Labels of a Switch Statement as a Collection in Java 8?

我已经为文本文件中的典型文本格式(专有)编写了一个解析器。解析器的主要任务之一是转换调用中的函数名称,其次是改变参数 and/or 它们在调用中的位置。

示例:

Func1(bla1,bla2,bla3)

变成

Func2(bla1) // again, licensing issues, so cannot show the actual file

至少有 50 个独立的此类函数。该程序运行良好。唯一的问题是,如果将来添加一些新函数,我将不得不改变两件事,一个 ArrayList ,它包含所有需要修改其调用的函数的名称,以及一个实际修改调用的 switch 语句。可能会发生这样的情况,一个特定的函数名称作为一个案例出现在 switch 语句中,但我是一个健忘的怪胎,函数名称不存在于 ArrayList 中。
我在想的是,如果我可以让 Java 为我生成那个 ArrayList(它只是一个字符串列表,每个条目都是一个 case 标签),它可能会有所帮助。 Java 8 中有什么方法可以做到这一点吗?

示例:

String functionName = "";
switch(functionName) {
case "Func1":
    break;
case "Func2":
    break;
//bla bla bla
default:
    //whatever
} 

List<String> functionNames = <some code which returns a Collection of all case names>;

来自 Java 语言规范 : 14.11. The switch Statement click the link , you can see that cases of the Switch can be a ConstantExpression or an EnumConstantName and following the definition of the ConstantExpression here click the link .

所以每个case语句中的值必须是compile-time个与switch值相同数据类型的常量值(文字枚举常量,或final常量变量:用final修饰符标记并初始化)。


您正在寻找问题的答案:是否可以在运行时知道案例数量不可以,因为 cases 必须是编译时常量。

public class Swith {
    public static void main(String[] args) {
        List<String> lst = new ArrayList<>();
        switch (lst.get(0)) {
        case lst.get(0): //Compilation error : case expressions must be constant expressions
            break;
        default:
            break;
        }
    }
}

无法列出来自 switchcase 标签。

但是,您可以维护一个 Map,它将函数名称映射到它们对应的 actions-to-be-performed:

Map<String, Runnable> functions = Map.of(
    "func1", () -> doSomething(),
    "func2", () -> doSomethingElse(),
    ...
);

要获取函数名,您可以使用keySet() 获取所有函数名(或使用containsKey 检查函数名是否存在)。而不是 switch 语句,你可以只使用

functions.get(functionName).run();

请注意,我使用了 Runnable 作为映射值,它允许执行一些代码,无需输入。那是因为您没有显示您的 switch case 实际执行的操作,或者 " 改变参数 and/or 它们在调用中的位置" 实际看起来像什么。您可能想用更合适的内容替换 Runnable

您不能从开关中动态派生 case 语句的集合。但是,您可以创建一个函数枚举并在开关中使用它,然后 assemble 您的列表。例如...

public enum Function {
  FUNC1("func1"), FUNC2("func2"), ... ;
  private String functionName;
  private Function(String functionName) { ... }
  public String functionName() { ... }
  public static Function byFunctionName(String functionName) { ... }
}

找到与您当前打开的字符串相匹配的函数实例并打开该函数。

Function function = Function.byFunctionName(functionName);
switch (function) {
  case FUNCT1: ...
  case FUNCT2: ...
  ... etc ...
}

并且可以从同一个枚举创建函数名称列表。

List<String> functionNames = Arrays.stream(Function.values())
        .map(e -> e.functionName())
        .collect(Collectors.toList());