Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确保switch/case语句具有使用enum等所有选项?_Java_Enums_Switch Statement - Fatal编程技术网

Java 如何确保switch/case语句具有使用enum等所有选项?

Java 如何确保switch/case语句具有使用enum等所有选项?,java,enums,switch-statement,Java,Enums,Switch Statement,我想用Java创建一个switch/case语句,并确保所有字符串都在该语句中 但是,使用简单字符串(即北、南、东、西)在Java中创建枚举很容易 如何处理带有点和空格的字符串?i、 e.“这是描述”,“com.stackoverflow.ClassName”我认为这个问题的主要问题是,您的IDE告诉您switch语句中缺少枚举值。并询问您是否要添加它们而不是编译器。当然,这并不能确保枚举类的用户必须使用每个值 Joshua Bloch在其有效的Java书籍(第章使用接口模拟可扩展枚举)中提到了

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

但是,使用简单字符串(即北、南、东、西)在Java中创建枚举很容易


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

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

Joshua Bloch在其有效的Java书籍(第章<代码>使用接口<代码>模拟可扩展枚举)中提到了一种方法,该接口可以更改为与此处显示的交换机一起使用:。但我认为交换机解决方案不能提供使用所有枚举的完全安全性

但是,既然您想知道是否有使用字符串的解决方案,我们也可以尝试使用如下所示的函数式方法:并使其使用字符串字段而不是枚举

这可能如下所示:

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语句,则可以使用这种方法。在其他任何地方,您都应该坚持使用枚举的方法

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

  • :但这仅包括switch语句的默认分支
  • :注释处理器,它在编译时检查是否处理了所有枚举常量

  • 如果您询问是否可以创建一个
    enum
    ,其中常量有空格,那么答案是“no

    枚举常量是普通的Java标识符,与类或变量名类似,因此它们不能包含空格或特殊字符


    但是,是否无法将枚举与字符串链接?否。
    如果出于某种原因,您希望您的开关盒使用
    enum
    以确保可读性/简洁性,但您的输入是
    字符串,可以有空格特殊字符,那么有一种方法

    您需要扩展
    枚举
    ,以便有一个额外的字段(我们称之为标签)来保存此
    字符串

    在使用
    enum
    的开关案例的方法中,可以调用
    findByLabel
    方法
    返回与提供的
    字符串
    对应的
    枚举

    下面是一个使用
    enum
    值NORTH、EAST、SOUTH、WEST的小示例类
    链接到不同(无效枚举命名)结构的
    字符串

    public class EnumExample {
    
        enum SwitchEnum {
            NORTH   ("North star"),
            EAST    ("Eastpack rulez!"),
            SOUTH   ("https://www.southafrica.net/"),
            WEST    ("java.awt.BorderLayout.WEST");
    
            private final String label;
            SwitchEnum(final String label) {
                this.label = label;
            }
    
            @Override
            public String toString() {
                return this.label;
            }
    
            private static final Map<String,SwitchEnum> map;
            static {
                map = new HashMap<String,SwitchEnum>();
                for (SwitchEnum v : SwitchEnum.values()) {
                    map.put(v.label, v);
                }
            }
            public static SwitchEnum findByLabel(String label) {
                return map.get(label);
            }
        }
    
        public static String doEnumSwitch(String enumString) {
            SwitchEnum enm = SwitchEnum.findByLabel(enumString);
            if (enm != null) {
                String enumReturn = enm.name() +" : "+ enm;
                switch (enm) {
                    case NORTH:
                        return enumReturn +" - Up there.";
                    case EAST:
                        return enumReturn +" - Now for sale.";
                    case SOUTH:
                        return enumReturn +" - Now with 50% more elephants.";
                    default:
                        return "UNHANDLED ENUM : "+ enm.name() +" - "+ enm;
                }
            } else {
                return "UNKNOWN ENUM : "+ enumString;
            }
        }
    
        public static void main(String[] args) {
            System.out.println(doEnumSwitch("North star"));
            System.out.println(doEnumSwitch("Eastpack rulez!"));
            System.out.println(doEnumSwitch("https://www.southafrica.net/"));
            System.out.println(doEnumSwitch("java.awt.BorderLayout.WEST"));
            System.out.println(doEnumSwitch("I only want to get out of here."));
        }
    }
    
    公共类枚举示例{
    枚举开关枚举{
    北方(“北极星”),
    东(“东包规则!”),
    南部(”https://www.southafrica.net/"),
    WEST(“java.awt.BorderLayout.WEST”);
    私有最终字符串标签;
    SwitchEnum(最终字符串标签){
    this.label=标签;
    }
    @凌驾
    公共字符串toString(){
    返回此.label;
    }
    私有静态最终地图;
    静止的{
    map=新的HashMap();
    对于(SwitchEnum v:SwitchEnum.values()){
    地图放置(v.标签,v);
    }
    }
    公共静态开关枚举findByLabel(字符串标签){
    返回map.get(标签);
    }
    }
    公共静态字符串doEnumSwitch(字符串enumString){
    SwitchEnm enm=SwitchEnum.findByLabel(enumString);
    如果(enm!=null){
    字符串enumReturn=enm.name()+“:”+enm;
    开关(enm){
    案例北:
    return枚举return+“-在上面。”;
    案例东:
    return枚举return+“-现在出售。”;
    南方案例:
    return enumReturn+“-现在大象多了50%。”;
    违约:
    返回“未处理的枚举:”+enm.name()+“-”+enm;
    }
    }否则{
    返回“未知枚举:”+enumString;
    }
    }
    公共静态void main(字符串[]args){
    System.out.println(doEnumSwitch(“北极星”);
    System.out.println(doEnumSwitch(“Eastpack rulez!”);
    System.out.println(doEnumSwitch(“https://www.southafrica.net/"));
    System.out.println(doEnumSwitch(“java.awt.BorderLayout.WEST”);
    System.out.println(doEnumSwitch(“我只想离开这里”);
    }
    }
    
    这将产生以下结果

    北方:北极星-在那里。
    东:东包规则!-现在出售。
    南部:-现在大象多了50%。
    未处理的枚举:WEST-java.awt.BorderLayout.WEST
    未知枚举:我只想离开这里


    恐怕你的问题不清楚。你所说的“确保所有字符串都在语句中”是什么意思。那些字符串是什么?通过将它们添加到事例列表中,Java编译器不知道“NORTH”是一组基本方向的一部分。怎么做呢?通过使用枚举。它们正在做你想要做的事情。@kumesana警告,是的,毫无疑问像sonar这样的库也会注意到它。不幸的是,这并不能保证所有的案例都得到处理,它只会告诉你一些没有得到处理。至于默认设置:就个人而言,我尝试毕竟:如果我想让它们得到相同的对待,我不需要不同的值。这里的危险在于