当前位置: 首页 > 面试题库 >

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

黄泰宁
2023-03-14
问题内容

因此,我正在研究具有一些静态常量的此类:

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

但是,当我编译时,constant expression required在3个大小写标签的每一个上都出现错误。

我知道编译器需要在编译时就知道表达式才能编译开关,但是为什么不是Foo.BA_常量?


问题答案:

尽管从初始化字段之后执行的任何代码的角度来看,它们是恒定的,但从JLS 的角度来看,它们不是编译时常数。有关常量表达式1的规范,请参见第15.28节常量表达式。这是指第4.12.4节“最终变量”,它定义了以下“常量”:

我们将原始类型或String类型的变量称为最终变量,该变量是最终变量并使用编译时常量表达式(第15.28节)进行初始化。变量是否为常数变量可能与类初始化(第12.4.1节),二进制兼容性(第13.1节,第13.4.9节)和确定赋值(第16节)有关。

在您的示例中,Foo.BA *变量没有初始化程序,因此不属于“常量变量”。解决方法很简单;更改Foo.BA *变量声明,使其具有作为编译时常量表达式的初始化程序。

在其他示例中(初始化程序已经是编译时常量表达式),将变量声明final为需要的变量。

您可以更改代码以使用enum而不是int常量,但这带来了另外两个不同的限制:

你必须有一个default情况下,即使你有case对的每一个已知值enum; 请参阅为什么打开枚举需要默认值?
该case标签都必须明确的enum值,而不是计算结果为表达式的enum值。
1-常量表达式限制可以总结如下。常量表达式A)可以使用原语类型和String只,b)容许是文字(除了初选null)和恒定变量只,C)允许常量表达式可能parenthesised作为子表达式,d)允许操作员除了赋值运算符,++--instanceof,和e)允许类型转换为原始类型或String仅转换为原始类型。

请注意,这并不包括任何形式的方法或lambda调用,new,.class。.length或数组下标。此外,enum由于a),排除了对数组值,值,原始包装器类型的值,装箱和拆箱的任何使用。



 类似资料:
  • 问题内容: 我的转换案例声明昨天运行良好。但是,当我今天早些时候运行代码时,eclipse给我一个错误,强调了红色的case语句,并说:case表达式必须是常量表达式,它是常量,我不知道发生了什么。这是我的代码如下: 所有R.id.int都用红色下划线。 问题答案: 在常规的Android项目中,资源R类中的常量声明如下: 但是,从ADT 14开始,在图书馆项目中,它们将这样声明: 换句话说,常数

  • C 14中的§5.19/3定义了积分常量表达式和转换常量表达式: 整数常量表达式是整数或无作用域枚举类型的表达式,隐式转换为prvalue,其中转换的表达式是核心常量表达式。[注意:此类表达式可用作数组边界(8.3.4, 5.3.4),作为位字段长度(9.6),如果基础类型不固定,则可用作枚举器初始化器(7.2),并用作对齐(7.6.2)。-结束注释]类型的转换常量表达式是一个表达式,隐式转换为类

  • 常量表达式机制是为了: 提供一种更加通用的常量表达式 允许用户自定义的类型成为常量表达式 提供了一种保证在编译期完成初始化的方法(可以在编译时期执行某些函数调用) 考虑下面这段代码: enum Flags { good=0, fail=1, bad=2, eof=4 }; constexpr int operator|(Flags f1, Flags f2) { return Flags(int(

  • 在我的应用程序(这是一个Android游戏)中,我有一个方法可以检查玩家是否还活着,如果没有,运行一个动画,游戏就结束了。 根据玩家的输球方式,目前有3种不同的动画可用。 例如,它们可能从屏幕上掉下来,撞到一只鸟,或者被从天上掉下来的东西压扁。每一个都有不同的动画。 基本上,我正在做的是: 当玩家输球时,我设置了它发生的方法,例如,如果他们被鸟击中: 然后我通过在我的check Gameover(

  • 问题内容: 我在switch / case语句中遇到问题。该错误显示:“ case表达式必须是常量表达式”。我理解该错误,可以使用If来解决它,但是有人可以告诉我为什么case表达式在switch / case中必须是常量。我的错误的代码示例: 谢谢你的解释!! 问题答案: 因此可以在编译阶段进行评估(静态检查) 请参阅:http://docs.oracle.com/javase/specs/jl

  • N4527 5.20【expr.const】p5 常量表达式是glvalue核心常量表达式,其值是指常量表达式(定义如下)的允许结果实体,或者是prvalue核心常量表达式,其值是对象,其中,对于该对象及其子对象: -引用类型的每个非静态数据成员引用一个实体,该实体是常量表达式的允许结果,并且 -如果对象或子对象是指针类型,则它包含具有静态存储持续时间的对象的地址、超过此类对象结尾的地址(5.7)