热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

技术大佬:我去,你写的switch语句也太老土了吧!

作者|沉默王二来源|CSDN博客专家出品|CSDN(ID:CSDNnews)昨天早上通过远程的方式review了两名新来同事的代码,大部分

作者 | 沉默王二

来源 | CSDN 博客专家

出品 | CSDN(ID:CSDNnews)

昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!”

来看看小王写的代码吧,看完不要骂我装逼啊。

1private static String createPlayer(PlayerTypes playerType) {2    switch (playerType) {3        case TENNIS:4            return "网球运动员费德勒";5        case FOOTBALL:6            return "足球运动员C罗";7        case BASKETBALL:8            return "篮球运动员詹姆斯";9        case UNKNOWN:
10            throw new IllegalArgumentException("未知");
11        default:
12            throw new IllegalArgumentException(
13                    "运动员类型: " + playerType);
14
15    }
16}

看完上述代码后,你是不是会发出这样的感慨——“代码写得很好,没有任何问题啊!”是不是觉得我在无事生非,错怪了小王!但此时我要送上《了不起的盖茨比》中的一句话:

我年纪还轻,阅历不深的时候,我父亲教导过我一句话,我至今还念念不忘。“每逢你想要批评任何人的时候, ”他对我说,“你就记住,这个世界上所有的人,并不是个个都有过你拥有的那些优越条件。”

哈哈,这句话不光是让你看的,也是给我看的。是时候冷静下来谈谈上述 switch 语句的老土问题了。

看到上图了吧,当不小心删掉 default 语句后,编译器就会报错,提示:“没有返回语句”,为了解决这个问题,我们可以新建一个 player 变量作为返回结果,就像下面这样:

1private static String createPlayer(PlayerTypes playerType) {2    String player = null;3    switch (playerType) {4        case TENNIS:5            player = "网球运动员费德勒";6            break;7        case FOOTBALL:8            player = "足球运动员C罗";9            break;
10        case BASKETBALL:
11            player = "篮球运动员詹姆斯";
12            break;
13        case UNKNOWN:
14            throw new IllegalArgumentException("未知");
15    }
16
17    return player;
18}

当添加了 player 变量后,case 语句中就需要添加上 break 关键字;另外在 switch 语句结束后,返回 player。这时候,编译器并不会提示任何错误,说明 default 语句在这种情况下是可以省略的。

从 JDK 12 开始(本例使用的是 JDK 13),switch 语句升级了,不仅可以像传统的 switch 语句那样作为条件的判断,还可以直接作为一个返回结果。来对小王的代码进行改造,如下所示:

1private static String createPlayer(PlayerTypes playerType) {23   return switch (playerType) {45        case TENNIS -> "网球运动员费德勒";67        case FOOTBALL -> "足球运动员C罗";89        case BASKETBALL -> "篮球运动员詹姆斯";
10
11        case UNKNOWN ->  throw new IllegalArgumentException("未知");
12
13    };
14
15}

够 fashion 吧?不仅 switch 关键字之前加了 return 关键字,case 中还见到了 Lambda 表达式的影子,中划线和箭头替代了冒号,意味着箭头右侧的代码只管执行无须 break。

并且,default 语句变成了可选项,可有可无,不信?你也动手试试。

新的 switch 语句足够的智能化,除了有上述的 3 个优势,还可以对枚举类型的条件进行校验。假如在 PlayerTypes 中增加了新的类型 PINGPANG(乒乓球):

1public enum PlayerTypes {23    TENNIS,45    FOOTBALL,67    BASKETBALL,89    PINGPANG,
10
11    UNKNOWN
12
13}

此时编译器会发出以下警告:

意思就是 switch 中的 case 条件没有完全覆盖枚举中可能存在的值。好吧,那就把 PINGPANG 的条件加上吧。来看一下完整的代码:

1public class OldSwitchDemo {23    public enum PlayerTypes {45        TENNIS,67        FOOTBALL,89        BASKETBALL,
10
11        PINGPANG,
12
13        UNKNOWN
14
15    }
16
17
18
19    public static void main(String[] args) {
20
21        System.out.println(createPlayer(PlayerTypes.BASKETBALL));
22
23    }
24
25
26
27    private static String createPlayer(PlayerTypes playerType) {
28
29        return switch (playerType) {
30
31            case TENNIS -> "网球运动员费德勒";
32
33            case FOOTBALL -> "足球运动员C罗";
34
35            case BASKETBALL -> "篮球运动员詹姆斯";
36
37            case PINGPANG -> "乒乓球运动员马龙";
38
39            case UNKNOWN -> throw new IllegalArgumentException("未知");
40
41        };
42
43    }
44
45}

switch 语句变成了强大的 switch 表达式,美滋滋啊!那假如一个运动员既会打篮球又会打乒乓球呢?

1private static String createPlayer(PlayerTypes playerType) {23    return switch (playerType) {45        case TENNIS -> "网球运动员费德勒";67        case FOOTBALL -> "足球运动员C罗";89        case BASKETBALL,PINGPANG -> "牛逼运动员沉默王二";
10
11        case UNKNOWN -> throw new IllegalArgumentException("未知");
12
13    };
14
15}

就像上述代码那样,使用英文逗号“,”把条件分割开就行了,666 啊!

不服气?switch 表达式还有更厉害的,-> 右侧还可以是 {} 括起来的代码块,就像 Lambda 表达式那样。

1private static String createPlayer(PlayerTypes playerType) {23    return switch (playerType) {45        case TENNIS -> {67            System.out.println("网球");89            yield "网球运动员费德勒";
10
11        }
12
13        case FOOTBALL -> {
14
15            System.out.println("足球");
16
17            yield "足球运动员C罗";
18
19        }
20
21        case BASKETBALL -> {
22
23            System.out.println("篮球");
24
25            yield "篮球运动员詹姆斯";
26
27        }
28
29        case PINGPANG -> {
30
31            System.out.println("乒乓球");
32
33            yield "乒乓球运动员马龙";
34
35        }
36
37        case UNKNOWN -> throw new IllegalArgumentException("未知");
38
39    };
40
41}

细心的同学会发现一个之前素未谋面的关键字 yield,它和传统的 return、break 有什么区别呢?

先来看官方的解释:

A yield statement transfers control by causing an enclosing switch expression to produce a specified value.

意思就是说 yield 语句通过使一个封闭的 switch 表达式产生一个指定值来转移控制权。为了进一步地了解 yield 关键字,我们可以反编译一下字节码:

1private static String createPlayer(NewSwitchDemo3.PlayerTypes playerType) {23    String var10000;45    switch(playerType) {67        case TENNIS:89            System.out.println("网球");
10
11            var10000 = "网球运动员费德勒";
12
13            break;
14
15        case FOOTBALL:
16
17            System.out.println("足球");
18
19            var10000 = "足球运动员C罗";
20
21            break;
22
23        case BASKETBALL:
24
25            System.out.println("篮球");
26
27            var10000 = "篮球运动员詹姆斯";
28
29            break;
30
31        case PINGPANG:
32
33            System.out.println("乒乓球");
34
35            var10000 = "乒乓球运动员马龙";
36
37            break;
38
39        case UNKNOWN:
40
41            throw new IllegalArgumentException("未知");
42
43        default:
44
45            throw new IncompatibleClassChangeError();
46
47    }
48
49
50
51    return var10000;
52
53}

编译器在生成字节码的时候对 yield 关键字做了自动化转义,转成了传统的 break 语句。这下清楚了吧?

但是,话又说出来,那些看似 fashion 的代码也不过是把部分秀技的工作交给了编译器,还可能存在对旧版本不兼容、对队友不友好的问题——代码土点就土点呗,没准是最实用的。

“不好意思,我为昨天早上的嚣张向你道歉。。。。。。”我向小王发送了一条信息。

好了,我亲爱的读者朋友,以上就是本文的全部内容了,希望你学得开心。

原文链接:

https://blog.csdn.net/qing_gee/article/details/104586826

推荐阅读 

☞华为补助武汉员工,最高每日 2000 元;iPhone SE 2 量产或推迟;PowerShell 7.0 发布 | 极客头条

☞腾讯云“抢救”微盟!开 766 次在线会议、调拨 100 多台服务器、闹钟只敢定 2 小时

☞人工智能改变未来教育的5大方式!

☞Linux 会成为主流桌面操作系统吗?

☞6 个步骤,教你在Ubuntu虚拟机环境下,用Docker自带的DNS配置Hadoop | 附代码

☞开发项目时如何选择区块链平台?我们分析了以太坊、Bitcoin via RSK、Ardor三个有趣的平台来给你回答!

你点的每一个在看,我认真当成了喜欢



推荐阅读
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
author-avatar
手机用户2702932507
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有