首页 > 解决方案 > 如何确保 switch/case 语句具有使用枚举等所有选项?

问题描述

我想在 Java 中创建一个 switch/case 语句并确保所有字符串都在语句中。

但是,使用简单的字符串(即 NORTH、SOUTH、EAST、WEST)在 Java 中创建枚举很容易。

对于带有点和空格的字符串如何处理?即“这是描述”,“com.stackoverflow.ClassName”

标签: javaenumsswitch-statement

解决方案


我认为这个问题的主要问题是,您的 IDE 告诉您在 switch 语句中缺少枚举值。并询问您是否要添加它们而不是您的编译器。这当然不能确保您的枚举类的用户必须使用每个值。

Joshua Bloch 在他的 Effective Java 书中提到了一种方法(Emulated extensible enum using an interface可以更改为使用此处显示的开关的章节:Java Enum Switch。但我认为开关解决方案并不能提供使用所有枚举的完全安全性。

但是由于您想知道是否有使用字符串的解决方案,我们也可以尝试使用如下所示的函数方法:Enum Switch Functional Approach并使其与字符串字段而不是枚举一起使用。

这可能如下所示:

public class Direction {
    private static final String NORTH = "north";
    private static final String SOUTH = "south";
    private static final String EAST = "east";
    private static final String WEST = "west";

    public interface SwitchResult {
        void NORTH();
        void SOUTH();
        void EAST();
        void WEST();
    }

    public static void switchValue(String direction, SwitchResult result){
        switch (direction){
            case NORTH:
                result.NORTH();
                break;
            case SOUTH:
                result.SOUTH();
                break;
            case EAST:
                result.EAST();
                break;
            case WEST:
                result.WEST();
                break;
        }
    }

    public static void main(String[] args) {
        String direction = "west";
        Direction.switchValue(direction, new SwitchResult() {
            @Override public void NORTH() {
                System.out.println("this time north");
            }

            @Override public void SOUTH() {
                System.out.println("this time south");
            }

            @Override public void EAST() {
                System.out.println("this time east");
            }

            @Override public void WEST() {
                System.out.println("this time west");
            }
        });
    }
}

正如您在 main 方法中看到的那样,如果您想调用 switchValue 函数,您必须传递您的字符串和接口的实现,以确保您覆盖所有可能性。作为交换,代码是非常多余的。如果您只有对提供一堆字符串值的类具有读取权限并且您想围绕它构建一个 switch 语句,则可以使用这种方法。在其他任何地方,您都应该真正坚持使用枚举的方法。

如果您想使用第三方工具来真正确保无需编写任何多余的样板代码,请查看:

  1. FindBugs SF_SWITCH_NO_DEFAULT:但这仅涵盖 switch 语句的默认分支。
  2. @EnumMapper:注解处理器,在编译时检查所有枚举常量是否被处理

推荐阅读