IntelliJ IDEA Tutorials 开发工具

Java 12 和 IntelliJ IDEA

通过 switch 表达式,Java 12 正在增强其基本语言结构之一 – switch – 改善开发人员的日常编程体验。

优点是多方面的。与’传统’ switch 结构相比,switch 表达式可以返回值。使用 switch 分支定义多个常量的能力以及改进的代码语义使其简洁。通过删除 switch 分支的默认通过条件,降低了在 switch 表达式中引入逻辑错误的可能性。

在这篇博客中,我们将介绍使用现有 switch 语句的难点,定义 switch 表达式,并且解释它们为什么对您有好处。

我们开始吧。

传统 switch 架构

如果将 switch 架构视为多路条件,那么使用表达式似乎更合适。但在那之前,switch 只能用作语句。当前的 switch 语法受限且冗长。经常导致容易出错、难以调试的代码。

这是一个使用 switch 语句,根据给它的 size 来计算椅子 height 的示例:

public enum Size {S, M, L, XL};
public class Chair {
    public void calcHeight(Size size) {
        int height = 0; 
        switch (size) {
            case S:
                height = 18;
            case M:
                height = 20;
                break;
            case L:
                height = 25;
                break;
        }
    }
}

上述代码有几个问题:

  • 重复的 break 和赋值语句为代码添加噪声。

  • 代码冗长使其难以理解。

  • Switch 分支的默认通过条件潜藏逻辑错误 – case 标签 S 缺少的 break 语句让控制落入 case 标签 M。这导致当您执行 calcHeight(Size.S)时,height 值为 20 而不是 18。

Switch 表达式

让我们使用 switch 表达式重写前面的示例。在 IntelliJ IDEA 中,您可以对 switch 关键字使用 Alt+Enter 来查看建议。

 选择‘以增强的 switch 语句替换 (Replace with enhanced ‘switch’ statement)’,将传统 switch 语句转换为 switch 表达式:

上述代码有几个优点:

  • Switch 分支中的代码简洁易读。您在 -> 右边定义要执行的内容。

  • Switch 分支可以返回一个值,该值可用于为变量赋值。

  • Switch 分支需要 break 语句来标记其结束。缺少 break 语句,控制不会进入 switch 标签 – 从而避免逻辑错误。

返回值 vs.执行语句

当您不使用 switch 表达式返回值时,switch 分支可以选择执行语句或语句块,甚至抛出异常:

处理所有可能参数值

当您使用 switch 表达式返回一个值时,它应该可以处理所有可能的值,您可以将这些值作为参数传递给它。例如,如果您忘了与某个枚举常量对应的 case 标签,IntelliJ IDEA 可以检测到。它可以插入特定 case 标签或默认 case 标签。默认情况下,IntelliJ IDEA 根据变量类型插入默认值。

 您可以编辑占位符值:

枚举以外的类型可以有无限值。

当您传递 byteshortint 或 String 等类型,并且忘记包含default 标签,IntelliJ IDEA 可以检测到并修复这个问题:

在同一个 case 标签中定义多个常量

不同于 switch 语句,switch 表达式允许您在 case 标签中定义用逗号分隔的多个常量。

这样减少了代码冗余 – 您可以为所有 case 标签执行相同的代码。如果在 switch 表达式中为 case 标签定义了冗余代码,IntelliJ IDEA 可以修复这个问题:

Switch 分支中的局部变量和 break 语句

可以通过 switch 表达式在 switch 分支中定义局部变量。代码块必须包含指定要返回的值的break 语句:

enum Size {S, M, L, XL};

public class LocalVariablesWithSwitch {
    public void assignValue(Size size) {
        int height = 0;
        height = switch(size) {
            case S -> 18;
            case M -> {
                    int weight = 19;
                    break (weight > 10 ? 15 : 20); 
                } 
            case L, XL -> 25;
        };
    }
}

值 M 的 case 标签定义了一个块语句。代码块也可定义局部变量(本示例中的 weight)。局部变量 weight 的范围和可访问性仅限于 case 标签 M。请注意 switch 表达式如何使用 break 语句来返回值。

以防您忘记为 switch 分支定义返回值, 因此 IntelliJ IDEA 以下划线强调 case。当您把鼠标置于其上,可以查看关于缺少返回值的消息:

预演语言(Preview language)功能

Switch 表达式是一种预演语言功能。这基本上意味着即使它是完整的,也有可能在今后的 Java 版本中被确认为永久功能。这是有原因的。

Java 运行在数十亿台设备上,而且有数百万开发人员使用这种语言。Java 语言新功能的任何错误都会带来高风险。将某项语言功能永久加入 Java 前,Java 架构师会评估开发人员对它的看法 – 其好坏程度如何。根据反馈,在添加到 Java SE 前,可能会优化或完全删除预演功能。

所以,如果您有任何关于 Switch 表达式的反馈,请在此分享。

IntelliJ IDEA 配置

由于 Switch 表达式是一项 Java 12 语言功能,请下载并安装 OpenJDK 12,并且配置为与 IntelliJ IDEA 一起使用:

Java 正在不断发展,而 switch 表达式正是 Java 12 中一项受欢迎的变化。

快乐编程!

原文发表于2019年2月22日,作者 Mala Gupta

Discover more

网络研讨会视频:快速上手,使用 Kotlin 把支付宝小程序装进自己的 App

写一个 Android App 或许不难,但企业对于移动应用的要求愈来愈高,不只要求开发速度、稳定度、质量等,甚至希望能具备动态扩展的架构设计、在 App 中自启动小程序。面向这些需求,若是有好的开发工具及平台的支持,将可以大大降低开发及运维的成本。本次网络研讨会特别邀请到支付宝高级无线开发工程师温盛章为大家演示用 Kotlin 开发移动应用,并集成 mPaaS 让 App 具备小程序能力。 (本次视频已同步发表至 B 站) 主題分享 本次分享共有三个关键字: Kotlin 、 小程序 、 mPaaS 。温盛章首先从用户、开发、技术、平台等四大视角,向大家说明小程序是什么?简单来说,小程序就是一种拥有完整生命周期、应用间相互隔离、独立运行于宿主应用内的应用。而小程序从工作型 App、平台型 App、超级 App 到新阶段一路的演化历程,目前已经可以有接近 Native 的体验和顺畅、也可以有 H5 的快捷发布的优势。 对小程序有概念后,温盛章就以 Android Studio 演示如何在一个 Mobile App 里,以 Kotlin 撰写 Mobile App 的代码,并接上 mPaaS 平台,让 App 有自启动小程序的能力。要接入 mPaaS,首先需在 Android Studio 里安装 mPaaS 插件,并到阿里云的 mPaaS 后台创建一个新建用。接着,在 Andro

网络研讨会视频:重构还是重写?聊聊 Java 代码臭味与重构技巧

在重构一书里,将有问题的代码称作代码臭味(Code Smells,有些翻译成”代码异味”、”代码坏味道”),表示这份代码可能有设计上的问题、或是因为写得太凌乱而难以维护。总得来说,这份代码需要通过重构来改善。这样的场景往往是许多开发者的每日工作,因此,判定一位开发者的等级,往往就是看他的重构技巧是否熟练。本次网路研讨会特别邀请到 Odd-e 敏捷教练张博超(Jackson)为大家演示如何用 IntelliJ IDEA 的重构功能来改善 Java 代码臭味。 (本次视频已同步发表至 B 站) 主題分享 在本次的分享里,张博超先用一个日常工作的场景给大家举了个例子:我们在工作前可能会先收拾一下桌子、重启电脑、提前打开软件、在昨天写的代码上加注释,这些动作代表很多情况下,人会有直觉去做改善措施,这些改善措施的背后都会对应一个需要解决的问题。写代码也是类似的,每当我们说要改善代码前,需要先想清楚这个改善的目标是什么?是要解决什么问题?同时,我们也要思考这个改善的作法是不是能真正的解决问题? 为了让大家具体体现重构的过程,张博超以一个计算预算的代码为例子,实际以 IntelliJ IDEA 演示该怎么综合运用提取变量、提取方法、提取类、引入参数对象、修改构造函数等重构功能安全地修改代码,将一个原本高达 30 行、充满原始类型迷恋(Primitives Obsession)、过分亲密(In