开关表达式中的范围

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在日常实践中,Java 开发人员并不经常使用 switch 表达式。所以,我想,关于这种结构的知识不如“if-else”或“for”那么深。至少我的……我遇到了一个有趣的案例,想和你分享。让我们看一下代码:


 int state = ...
    ...
    List states = new ArrayList<>();
    switch (state) {
        case 0:
            Integer newState = orderState + 1;
            states.add(newState);
            break;
        case 1:
            newState = orderState + 2;
            states.add(newState);
            break;
        case 2:
            newState = orderState + 3;
            states.add(newState);
            break;
        default:
            newState = orderState + 4;
            states.add(newState);
        }

你认为这段代码正确吗?或者它应该看起来像这样:


 int state = ...
    ...
    List states = new ArrayList<>();
    switch (state) {
        case 0:
            Integer newState = orderState + 1;
            states.add(newState);
            break;
        case 1:
            newState = orderState + 2;
            states.add(newState);
            break;
        case 2:
            newState = orderState + 3;
            states.add(newState);
            break;
        default:
            newState = orderState + 4;
            states.add(newState);
        }

是否应该在每种 case 下都将 newState 声明为新变量?我的第一个意图是回答第一个变体是正确的。看起来很明显 switch if-else 相同,但内部有更多 if 情况。所以我们会在每个条件分支中声明一个新变量。

但这是不正确的。您应该在 switch 表达式中声明一次变量,然后在所有 case 块中使用它。可以解释的很简单:每个 case break 结尾,这会阻止处理所有后续的 case ,但 break 是可选的。如果没有 break 运算符,那么将执行第一种 case 下的所有运算符,然后执行第二种 case 下的所有运算符,依此类推。因此没有 break ,它是具有相同作用域的简单代码部分,所有运算符将在其中执行通常的顺序。

顺便提一下: { } 表示作用域的边界。 Switch 有一对 {} ,所以只有一个作用域,但是 if-else 可以有一对 {} 每个 if else 。这就是为什么可以在 if 部分和 else 部分中声明相同的变量。