1

I've defined an enumerated class "TestEnvEnum", and I've defined a class "ConfigInit" that calls the enumerated class.

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

Question: If I using Enum, so case TestEnvEnum.ENV2.name() and case TestEnvEnum.ENV3.name() will prompt "Constant expression required".

If I changed them to case "devEnv2" and case "devEnv3", the program will run correctly.

I want to know how I should use Enum in my program to avoid such an error. Pls help me.

sagr
  • 31
  • 4

3 Answers3

2

You can change it to something like this:

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

I would recommend you to read this post here which explains really good why this happens.

CodeMatrix
  • 2,124
  • 1
  • 18
  • 30
0

Every Enum value has a built in ordinal() which starts from 0 for ENV1, so there no need to add a switch to definition of scfInit().

So if you use the TestEnvEnum.byName code added by @CodeMatrix answer the definition of scfInit() is simply:

public static void scfInit() {
    TestEnvEnum testEnvEnum = TestEnvEnum.byName(envProps);
    envIndex = String.valueOf(testEnvEnum.ordinal()+1);
}
DuncG
  • 12,137
  • 2
  • 21
  • 33
-1

In your use case, it is responding with correct exception as you are passing envProp which is of type String so all the cases will we defined with string type but in your case you are evaluating the value by calling name() method which is unsupported so either you need to pass Enum type the switch so that it looks for enums otherwise convert your enum values to a string and use strig constants in place of expression.

Note: The case labels must all be explicit enum values, not expressions that evaluate to enum values.

e.g.

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

The above example will work.

Nitesh Sharma
  • 545
  • 3
  • 14
  • 1
    OP is expecting "devEnv1", "devEnv2", or "devEnv3" as the value of `System.getProperties().getProperty("env")`. –  Aug 08 '20 at 13:15
  • Yes and may I ask you what is incorrect in the mentioned answer for improvement – Nitesh Sharma Aug 08 '20 at 13:41
  • `TestEnvEnum.valueOf("ENV1")` returns `TestEnvEnum.ENV1`, but `TestEnvEnum.valueOf("devEnv1")` throws an `IllegalArgumentException`. –  Aug 08 '20 at 13:47