为什么“final static int”可用作开关的大小写常量而不是“最终静态<你的enum =”“>”</your>

时间:2010-12-09 18:27:43

标签: java enums constants case switch-statement

为什么这个int开关有效:


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

}

虽然这个枚举开关不是:


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

}

我知道案例中的内容必须是常量,那么为什么我可以使用“final static int”作为常量而不是“final static&lt; your enum&gt;”?

5 个答案:

答案 0 :(得分:17)

因为case语句标签必须具有编译时常量或EnumConstantName。 JLS 14.11

编译时间常量只能是字符串和基本类型,如JLS 15.28所述。因此,您不能使用静态final&lt; your enum&gt;,因为它既不是编译时常量,也不是枚举的名称。

答案 1 :(得分:8)

case参数必须是原始的;它不能成为一个对象。

但是,您可以按如下方式使用枚举:

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

因为value被声明为RetentionPolicy类型,所以您可以直接在交换机内使用枚举常量。

答案 2 :(得分:2)

或者只是使用if-elseif案例:

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

    }

}

答案 3 :(得分:1)

编译器说

unqualified enumeration constant name required

因此,RT的值必须为RUNTIME而不是RetentionPolicy.RUNTIME才能使您的代码正常工作。但当然这是不可能的。为什么不直接使用RetentionPolicy枚举?如果您想坚持最终的静态声明,则需要将整个枚举分配给最终的静态变量。

答案 4 :(得分:0)

我有类似的要求并通过打开Enums序号来解决这个问题,而不是打开enum本身。这不是很漂亮/直观但它有效:

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

}

请注意,当然不可能将常量声明为例如

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

出于同样的原因,人们首先无法将常量声明为枚举...