Java中switch的case标签只能是编译期可确定的常量表达式,包括字面量、final且声明时初始化的基本类型/String变量、enum常量;因需生成跳转表,故不支持运行时变量或方法调用。

Java 中 switch 语句的 case 标签必须是**编译期可确定的常量表达式**,不能是运行时才能计算出值的变量或方法调用。
哪些值可以作为 case 常量?
满足以下任一条件的表达式才被允许:
- 字面量(如
1、"abc"、true) - 被
final修饰且在声明时就初始化的基本类型或String变量(即“编译时常量”) -
enum的枚举常量(如Color.RED) - 从 Java 14 开始,
switch表达式支持record类型(需配合sealed和模式匹配,但普通case仍限于常量)
为什么不能用普通变量或方法调用?
因为 switch 在编译阶段需要生成跳转表(如 tableswitch 或 lookupswitch 字节码),这要求所有 case 值在编译时已知。例如:
错误示例:
立即学习“Java免费学习笔记(深入)”;
int x = 5;
final int y = 10;
switch (n) {
case x: // 编译错误:x 不是编译时常量
case getValue(): // 编译错误:方法调用非编译期常量
case y: // ✅ 正确:y 是 final 且直接初始化
}
String 和 enum 的特殊处理
从 Java 7 开始支持 String,但仅限字符串字面量或 final static String;JVM 内部会将其哈希值用于跳转,再额外做 equals 检查确保安全。枚举则直接使用其 ordinal() 和类信息,天然符合常量要求。
常见误区提醒
-
final int a = b + 1;—— 若b不是编译时常量,则a也不是 -
static final Integer N = 1;—— 包装类型不行,必须是基本类型或String/enum -
case 3 + 4:—— ✅ 合法,算术常量表达式在编译期求值为7









