331
votes

First I'll state that I'm much more familiar with enums in C# and it seems like enums in java is a quite mess.

As you can see, I'm trying to use a switch statement @ enums in my next example but I always get an error no matter what I'm doing.

The error I receive is:

The qualified case label SomeClass.AnotherClass.MyEnum.VALUE_A must be replaced with the unqualified enum constant VALUE_A

The thing is I quite understand the error but I can't just write the VALUE_A since the enum is located in another sub-class. Is there a way to solve this problem? And why is it happening in Java?

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        MyEnum enumExample //...

        switch (enumExample) {
            case AnotherClass.MyEnum.VALUE_A: { <-- error on this line
                //..
                break;
            }
        }
    }
}
7
As darrengorman commented, Java Enum are extremely handy once you get the hang of them – not at all a mess. They are much more flexible and practical than simple enums (merely a labeled integer value) as seen on other platforms. See the Oracle Tutorial. Discover the optimized Set/Map implementations: EnumSet & EnumMap.Basil Bourque
When you try to qualify the case statement; in a way, you are trying to say that I can mix different types of enums (not just same enum type) within a single switch statement. Java has stopped it with this approach as discussed here digizol.com/2010/10/enum-case-label-switch-java-qualified.htmllkamal
This happened to me while refactoring (moving) a class in IntelliJ 2018.2Daniel Alder

7 Answers

684
votes

Change it to this:

switch (enumExample) {
    case VALUE_A: {
        //..
        break;
    }
}

The clue is in the error. You don't need to qualify case labels with the enum type, just its value.

38
votes

Java infers automatically the type of the elements in case, so the labels must be unqualified.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}
23
votes

Wrong:

case AnotherClass.MyEnum.VALUE_A

Right:

case VALUE_A:
5
votes

this should do:

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        AnotherClass.MyEnum enumExample = AnotherClass.MyEnum.VALUE_A; //...

        switch (enumExample) {
            case VALUE_A: { //<-- error on this line
            //..
            break;
            }
        }
    }
}
2
votes

This is how I am using it. And it is working fantastically -

public enum Button {
        REPORT_ISSUES(0),
        CANCEL_ORDER(1),
        RETURN_ORDER(2);

        private int value;

        Button(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

And the switch-case as shown below

@Override
public void onClick(MyOrderDetailDelgate.Button button, int position) {
    switch (button) {
        case REPORT_ISSUES: {
            break;
        }
        case CANCEL_ORDER: {
            break;
        }
        case RETURN_ORDER: {
            break;
        }
    }
}
1
votes

From Java 14 onwards, one can use switch expressions.

For this post

public enum MyEnum {
    VALUE_A, VALUE_B;
}
public void someMethod() { 
    MyEnum enumExample //...

    switch (enumExample) {
        case VALUE_A -> {
            // logic
        }
        case VALUE_B -> {
            // logic
        }   
    }
}

Switch expression

Like all expressions, switch expressions evaluate to a single value and can be used in statements. They may contain "case L ->" labels that eliminate the need for break statements to prevent fall through. You can use a yield statement to specify the value of a switch expression.

public enum Month {
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC;
}

Example 1: Returns value.

public static int getNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    return switch(month) {
        case APR, JUN, SEP, NOV -> 30;
        case FEB -> (isLeapYear)? 29: 28;
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
    };
}

Example 2: Doesn't returns value.

public static void printNoOfDaysInAMonth(Month month, boolean isLeapYear) {
    switch(month) {
        case APR, JUN, SEP, NOV -> {
            System.out.println("30 days");
        }
        case FEB -> {
            System.out.println(((isLeapYear)? 29: 28) + " days");
        }
        case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> {
            System.out.println("31 days");
        }
    };
}

Reference

Switch Expressions

0
votes

Write someMethod() in this way:

public void someMethod() {

    SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A;

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

In switch statement you must use the constant name only.