小编典典

在Java开关中声明和初始化变量

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-当key为2时,它成功地将值打印为2。
方案2-当我要在其中注释value = 2case 2:,saying地说 “本地变量值可能尚未初始化”

问题:

场景1:如果执行流程没有转到case 1:(当时key = 2),那么它如何知道value变量的类型为int

方案2:如果编译器将value变量的类型识别为int,则它必须已访问。(声明和初始化)中的int value = 1;表达式case 1:。那为什么它会吱吱作响?当我要发表评论value = 2case 2:,说 本地变量值可能没有初始化


阅读 421

收藏
2020-09-08

共1个答案

小编典典

基本上,switch语句的作用域很奇怪。从JLS的6.3节开始

块中的局部变量声明的范围(第14.4节)是该声明在其中出现的其余部分,从其自身的初始化程序开始,并在局部变量声明语句的右侧包括其他任何声明符。

在您的情况下,即使永远不会执行,它也与它case 2位于同 一块中case 1并在其后出现case 1……因此,即使您从逻辑上也从未“执行”该声明,该局部变量仍在范围内并且可用于 编写 。(尽管声明是初始化的,但它并不是真正的“可执行文件”。)

如果您注释掉该value = 2;赋值,编译器仍会知道您所指的是哪个变量,但是您将不会经历任何为其赋值的执行路径,这就是为什么您尝试执行此操作时会收到错误的原因读取其他任何未明确分配的局部变量。

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

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

我相信这很清楚。

2020-09-08