为什么“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();
出于同样的原因,人们首先无法将常量声明为枚举…