繁体   English   中英

将 Enum 与 switch 语句一起使用:需要常量表达式错误

[英]Use Enum with switch statement: constant expression required error

我定义了一个枚举的 class“TestEnvEnum”,并且我定义了一个调用枚举的 class 的 class“ConfigInit”。

public enum TestEnvEnum {
    ENV1("devEnv1"),
    ENV2("devEnv2"),
    ENV3("devEnv3");

    private final String name;

    TestEnvEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}


public class ConfigInit {
    static String envIndex = "1";
    static String envProps = System.getProperties().getProperty("env");
    public static void scfInit() {
        switch (envProps) {
            case TestEnvEnum.ENV2.name():  //error: Constant expression required
                envIndex = "2";
                break;
            case TestEnvEnum.ENV3.name():  //error: Constant expression required
                envIndex = "3";
                break;
            default:
                envIndex = "1";
        }
    }
}

问题:如果我使用 Enum,那么 case TestEnvEnum.ENV2.name() 和 case TestEnvEnum.ENV3.name() 会提示“需要常量表达式”。

如果我将它们更改为“devEnv2”和“devEnv3”,程序将正确运行。

我想知道我应该如何在我的程序中使用 Enum 来避免这样的错误。 请帮助我。

你可以把它改成这样:

public enum TestEnvEnum {
    ENV1("devEnv1"),
    ENV2("devEnv2"),
    ENV3("devEnv3");

    private final String name;

    TestEnvEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }

    public static TestEnvEnum byName(String name) { //You may change the return type to Optional<TestEnvEnum> to avoid NPE
        for (TestEnvEnum value : values()) {
            if(value.getName().equals(name)) { //equalsIgnoreCase should be used if you don't care about the capitalization
                return value;
            }
        }
        return null;
    }
}

public class ConfigInit {
    static String envIndex = "1";
    static String envProps = System.getProperties().getProperty("env");
    public static void scfInit() {
        TestEnvEnum testEnvEnum = TestEnvEnum.byName(envProps);
        switch (testEnvEnum) {
            case ENV2:
                envIndex = "2";
                break;
            case ENV3:
                envIndex = "3";
                break;
            default:
                envIndex = "1";
        }
    }
}

我建议您在这里阅读这篇文章,它很好地解释了为什么会发生这种情况。

每个 Enum 值都有一个内置的 ordinal(),它从 ENV1 的 0 开始,因此无需在 scfInit() 的定义中添加开关。

因此,如果您使用 @CodeMatrix 添加的TestEnvEnum.byName代码,则 scfInit() 的定义很简单:

public static void scfInit() {
    TestEnvEnum testEnvEnum = TestEnvEnum.byName(envProps);
    envIndex = String.valueOf(testEnvEnum.ordinal()+1);
}

在您的用例中,它会以正确的异常响应,因为您传递的是 String 类型的envProp ,因此我们将使用字符串类型定义所有情况,但在您的情况下,您正在通过调用不受支持的name()方法来评估值所以要么您需要传递 Enum 类型的开关,以便它查找枚举,否则将您的枚举值转换为字符串并使用字符串常量代替表达式。

注意:case 标签必须都是明确的枚举值,而不是计算为枚举值的表达式。

例如

enum TestEnvEnum {
    ENV1("devEnv1"),
    ENV2("devEnv2"),
    ENV3("devEnv3");

    private final String name;

    TestEnvEnum(String name) {
        this.name = name;
    }

     public static TestEnvEnum enumValue(String name) {
     return Arrays.stream(values()).filter(value -> name.equalsIgnoreCase(value.name)).findFirst()
            .orElse(null);
}

    @Override
    public String toString() {
        return name;
    }
}


public class SampleEnum {
    static String envIndex = "1";
    
    public static void scfInit() {
        TestEnvEnum envProps = TestEnvEnum.enumValue(System.getProperties().getProperty("env"));
        switch (envProps) {
            case ENV2:  
                envIndex = "2";
                break;
            case ENV3:  
                envIndex = "3";
                break;
            default:
                envIndex = "1";
        }
    }
}

上面的示例将起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM