开发者

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

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>"?


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.


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.


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)){

    }

}


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.


I had a similar requirement and worked around this problem by switching on the Enums ordinal number instead of switching on the enum itself. This is not very beautiful/intuitive but it works:

public class Foo {

    private final static int SRC = 0; // == RetentionPolicy.SOURCE.ordinal();
    private final static int RT = 2; // == RetentionPolicy.RUNTIME.ordinal();

    static{
        if (RT != RetentionPolicy.RUNTIME.ordinal() || SRC !=  RetentionPolicy.SOURCE.ordinal()) {
            throw new IllegalStateException("Incompatible RetentionPolicy.class file");
        }
    }

    public static void main(String[] args) {
        RetentionPolicy value = RetentionPolicy.RUNTIME;
        switch (value.ordinal()) {
            case RT: break;
            case SRC: break;
        }
    }

}

Note that it is of course not possible to declare the constant as e.g.

private final static int SRC = RetentionPolicy.SOURCE.ordinal();

for the same reason one is not able to declare the constant as an Enum in the first place...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜