在 Java 交换机中声明和初始化变量

我有一个关于Java开关的疯狂问题。

int key = 2;

switch (key) {
    case 1:
        int value = 1;
        break;
    case 2:
        value = 2;
        System.out.println(value);
        break;
    default:
        break;
}

方案 1 - 当 为 2 时,它将成功将值打印为 2。
场景 2 - 当我要在其中发表评论时,会发出警告,说局部变量值可能尚未初始化keyvalue = 2case 2:

问:

场景1:如果执行流没有去(当),那么它怎么知道值变量的类型为?

场景 2:如果编译器知道值变量的类型为 ,则它必须访问过 中的表达式。(声明和初始化)。那么为什么它 sqawrk 当我要注释时,说局部变量值可能尚未初始化case 1:key = 2intintint value = 1;case 1:value = 2case 2:


答案 1

基本上,Switch 语句在范围方面是奇怪的。从 JLS 的第 6.3 节中可以看出:

块中局部变量声明的作用域 (§14.4) 是声明所在的块的其余部分,从其自己的初始值设定项开始,并在局部变量声明语句中包括右侧的任何其他声明符。

在你的情况下,与它在同一中,并出现在它之后,即使永远不会执行...因此,局部变量在范围内并且可以编写,尽管您在逻辑上从不“执行”声明。(声明并不是真正的“可执行”,尽管初始化是。case 2case 1case 1

如果您注释掉了赋值,编译器仍然知道您引用的变量,但您不会经历任何为其赋值的执行路径,这就是为什么当您尝试读取任何其他未明确赋值的局部变量时,您会遇到错误的原因。value = 2;

我强烈建议您不要使用在其他情况下声明的局部变量 - 正如您所看到的,这会导致高度混乱的代码。当我在 switch 语句中引入局部变量时(我很少尝试这样做 - 理想情况下,情况应该非常短),我通常更喜欢引入一个新的作用域:

case 1: {
    int value = 1;
    ...
    break;
}
case 2: {
    int value = 2;
    ...
    break;
}

我认为这一点更清楚。


答案 2

变量已被声明(作为 int),但尚未初始化(分配了初始值)。想想这条线:

int value = 1;

如:

int value;
value = 1;

该部分在编译时告诉编译器,您有一个名为 value 的变量,它是一个 int。该部分初始化它,但这发生在运行时,如果没有输入交换机的该分支,则根本不会发生。int valuevalue = 1