为什么不能在switch语句中使用final变量?

5
当我在Eclipse中输入以下代码时,它会抱怨“case表达式必须是常量表达式”。如果数组被标记为final,那么它的内容必须是常量。为什么这是无效的?
final String[] match={"a","b","c"};
switch (switchVar) {
case match[0]: /* Eclipse complains here about nonconstant switch */
    System.out.println("Matches");
    break;
default:
    System.out.println("No Match");
    break;
}
3个回答

6

数组是不稳定的,它的内容可能随时被更改。引用可能保持不变,但match[0]在任何时间点上都可能是不同的。

你必须使用一个常量值,这个值保证不会改变。像枚举、基本字面量(和它们的包装器)和String字面量在这个过程中是保证不会改变的,并且可以使用。

然而,这意味着你可以使用一个标记为final并且不可变的变量。由于数组类型是可变的,即使将其重新分配给一个final变量也不太好用。你必须声明字面量。

下面是一个简单的代码片段,修改了你现有的代码:

String switchVar = "a";
final String matchZero = "a";
switch (switchVar) {
    case matchZero: // valid since there's no way matchZero can ever be mutated
        System.out.println("Matches");
        break;
    default:
        System.out.println("No Match");
        break;
}

你的报价没有“强调这一点”。语法是:SwitchLabel: case ConstantExpression: case EnumConstantName: default:。你的报价是关于 switch 部分中 switch-expression 内容的说明。 - user207421
@EJP:那可能会读起来有点令人困惑;我同意。我已经重新措辞了。 - Makoto
令人困惑的?这是不相关的。 - user207421

2
如果数组被标记为final,它的内容必须是常量。
这是一个错误的理解。final变量只能防止创建新的数组实例,但不能防止更改数组的内容。使用您现有的代码,我可以这样做并且它将是有效的:
    final String[] match = {"a", "b", "c"};        
    match[0] = "b"; // CHANGE HERE
    switch (switchVar) {
        case "a": //Fixing this to make it compile
            /* Eclipse complains here about nonconstant switch */
            System.out.println("Matches");
            break;
        default:
            System.out.println("No Match");
            break;
    }

为了使代码编译并使用switch语句,你需要使用常量。因此,声明常量或使用内部字符串都可以使其工作。
    final String[] match = {"a", "b", "c"};        
    switch (switchVar) {
        case "a": // CHANGE HERE
            /* Eclipse complains here about nonconstant switch */
            System.out.println("Matches");
            break;
        default:
            System.out.println("No Match");
            break;
    }

这是因为Java语言规范中关于switch语句的说明假定所有的switch语句都作用于常量表达式。

0

你的问题的重点是“最终的”,

final String[] match = {"a", "b", "c"};

这意味着数组match的地址不能被改变,但并不意味着数组match的值不能被改变。
而且case语句需要一个常量值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接