Java switch语句:需要常量表达式,但它是常量

问题

所以,我正在研究这个有一些静态常量的类:

public abstract class Foo {
    ...
    public static final int BAR;
    public static final int BAZ;
    public static final int BAM;
    ...
}

然后,我想要一种基于常量获取相关字符串的方法:

public static String lookup(int constant) {
    switch (constant) {
        case Foo.BAR: return "bar";
        case Foo.BAZ: return "baz";
        case Foo.BAM: return "bam";
        default: return "unknown";
    }
}

但是,当我编译时,我会在3个案例标签中得到aconstant expression required错误。

我理解编译器需要在编译时知道表达式来编译一个开关,但为什么不是Foo.BA_常量?


#1 热门回答(115 赞)

我理解编译器需要在编译时知道表达式来编译一个开关,但为什么不是Foo.BA_常量?

虽然从字段初始化后执行的任何代码的角度看它们是不变的,但它们不是JLS所要求的意义上的编译时间常数;参见§15.28 Constant Expressions,了解常量表达式的要求。这指的是§4.12.4 Final Variables,它定义了一个"常量变量",如下所示:

我们调用一个原始类型或类型String的变量,它是final,并使用编译时常量表达式(第15.28节)初始化为常量变量。变量是否是常量变量可能对类初始化(第12.4.1节),二进制兼容性(第13.1节,第13.4.9节)和明确赋值(第16节)有影响。

在你的示例中,Foo.BA *变量没有初始值设定项,因此不符合"常量变量"的条件。修复很简单;将Foo.BA *变量声明更改为具有编译时常量表达式的初始值设定项。


#2 热门回答(60 赞)

你需要getConstant表达式,因为你将值保留在常量上。尝试:

public abstract class Foo {
    ...
    public static final int BAR=0;
    public static final int BAZ=1;
    public static final int BAM=2;
    ...
}

#3 热门回答(30 赞)

我在Android上遇到此错误,我的解决方案就是使用:

public static final int TAKE_PICTURE = 1;

代替

public static int TAKE_PICTURE = 1;