Why "final static int" can be used as a switch's case constant but not "final static <your enum>"

17,698

Solution 1

Because a case statement label must have either a compile time constant or an EnumConstantName. JLS 14.11

Compile time constants can only be strings and primitive types, as described by JLS 15.28. Thus you can not use a static final <your enum>, as it is neither a compile time constant, nor the name of an enum.

Solution 2

The case argument must be primitive; it cannot be an object.

However, you can use enums as follows:

RetentionPolicy value = ...
switch (value) {
    case RUNTIME:
    case SOURCE:
}

Because value is declared to be of type RetentionPolicy you can use the enum constants directly inside the switch.

Solution 3

Or simply use a if-elseif case :

private final static int ONE = 1;
private final static int TWO = 2;

public static void main(String[] args) {
    int value = 1;

    if(value.equals(ONE)){

    }
    else if(value.equals(ONE)){

    }

}

Solution 4

The compiler says

unqualified enumeration constant name required

So your value of RT would need to be RUNTIME instead of RetentionPolicy.RUNTIME to make your code work. But of course that is not possible. Why not use the RetentionPolicy enum directly? If you want to stick to your final static declaration, you need to assign the whole enum to your final static variable.

Share:
17,698
pakman
Author by

pakman

Updated on June 05, 2022

Comments

  • pakman
    pakman about 2 years

    Why is this int switch valid:

    
    public class Foo {
        private final static int ONE = 1;
        private final static int TWO = 2;
    
        public static void main(String[] args) {
            int value = 1;
            switch (value) {
                case ONE: break;
                case TWO: break;
            }
        }
    
    }
    

    While this enum switch is not:

    
    import java.lang.annotation.RetentionPolicy;
    
    public class Foo {
        private final static RetentionPolicy RT = RetentionPolicy.RUNTIME;
        private final static RetentionPolicy SRC = RetentionPolicy.SOURCE;
    
        public static void main(String[] args) {
            RetentionPolicy value = RetentionPolicy.RUNTIME;
            switch (value) {
                case RT: break;
                case SRC: break;
            }
        }
    
    }
    

    I know that what goes in the case must be a constant, so why can I use a "final static int" as constant but not a "final static <your enum>"?

  • Buhake Sindi
    Buhake Sindi over 13 years
    RetentionPolicy is an enum.
  • Cameron Skinner
    Cameron Skinner over 13 years
    @Michael: The OP used final static variables instead of direct references to the enum constants.
  • Cameron Skinner
    Cameron Skinner over 13 years
    @Elite: Er...yes? What is your question?
  • pakman
    pakman over 13 years
    Thanks for the response, but it does not answer my question. I know how to use a switch statement with enums as per your example.
  • pakman
    pakman over 13 years
    Did not understood your response. If you want to know why I want to do that see the comment I added to my post. Thanks for answering though.
  • user924272
    user924272 over 5 years
    That would work, but has non-deterministic knock on effects. For example, if code is relying on ordinals, rather than Enum values, you'll run into trouble when you insert another enum value. For clarity, consider that code could be splattered about which expects SOURCE.ordinal() to be 0. You can't guarantee this, if someone changes the RetentionPolicy in the future.
  • Balder
    Balder over 5 years
    Not entirely true: The code above is deterministic since the runtime check in the static initializer fails, if the ordinal numbers have changed for some reason. Of course this verification is very important and must not be omitted - thanks for pointing out this important detail!