407

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;
            }
        }
    }
}
3
  • 1
    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. Commented Aug 5, 2017 at 20:12
  • 3
    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.html Commented Nov 16, 2017 at 18:52
  • This happened to me while refactoring (moving) a class in IntelliJ 2018.2 Commented Jul 29, 2019 at 8:28

8 Answers 8

794

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.

Sign up to request clarification or add additional context in comments.

10 Comments

Ok i feel so stupid :-( You are totally right, i was convinced i tried this exact line and got an error with that so i moved to qualify case, but your suggestion DOES work.
By the way I think you'll find that enums in Java are incredibly useful once you start to use them more, I wouldn't say they're a mess at all :)
@milkplusvellocet, I know this post is already old, but I'm curious why Java don't allow the qualified case label in the switch statement?
@cRane01 don't know for sure, but it makes for a cleaner syntax. Specifying the type on each case would be totally redundant
@HelloGoodbye No. The switch statement's variable defines the type of the case statement so it can only be one enum.
|
63

Wrong:

case AnotherClass.MyEnum.VALUE_A

Right:

case VALUE_A:

2 Comments

I upvoted yours because it is clearer on what the issue is.
Why is it a problem to qualify it?
45

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
}

25 Comments

Why must it be unqualified?
If you could qualify, then you might use something else than MyEnum which would not make sense.
@Kru, but I can use something grammatically-else for non-enum-typed case expressions. E.g. static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;} instead of case 7. So this restriction for enums makes no sense (I can use not only primary literals, but also manually-defined constants for integer switch expression, but I can't use manually-defined constants, but only primary names for enums).
@Sasha enums in Java don't have integers assigned to them like in C++. They are abstract just like java boolean.
@user13947194, nobody said they have. I just pointed out the logical fallacy: for one type we can use both the primary literals and the manually-defined constants while for the other type we can use only primary names but not manually-defined constants.
|
7

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

Comments

6

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

1 Comment

You saved the day!
2

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

Comments

1

You dont need put instance of enum class, you have to put only enum constant of enum class, like this:

switch (enumExample) {
   case VALUE_A: { <-- puting only constant, it will works.
       //..
      break;
   }

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.