为什么“final static int”可以用作switch的case常量而不是“final static ”

为什么这个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 ”?

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

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

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

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

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

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

或者只是使用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)){ } } 

编译说

 unqualified enumeration constant name required 

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

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

 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(); 

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