趣文网,分享全网好句子、好文章!

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

时间:2023-05-19 02:17:01

相关推荐

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

作者 | 沉默王二

来源 | 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);1415 }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 }1617 return player;18}

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

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

1private static String createPlayer(PlayerTypes playerType) {2 3 return switch (playerType) { 4 5 case TENNIS -> "网球运动员费德勒"; 6 7 case FOOTBALL -> "足球运动员C罗"; 8 9 case BASKETBALL -> "篮球运动员詹姆斯";1011 case UNKNOWN -> throw new IllegalArgumentException("未知");1213 };1415}

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

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

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

1public enum PlayerTypes {2 3 TENNIS, 4 5 FOOTBALL, 6 7 BASKETBALL, 8 9 PINGPANG,1011 UNKNOWN1213}

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

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

1public class OldSwitchDemo {2 3 public enum PlayerTypes { 4 5 TENNIS, 6 7 FOOTBALL, 8 9 BASKETBALL,1011 PINGPANG,1213 UNKNOWN1415 }16171819 public static void main(String[] args) {2021 System.out.println(createPlayer(PlayerTypes.BASKETBALL));2223 }24252627 private static String createPlayer(PlayerTypes playerType) {2829 return switch (playerType) {3031 case TENNIS -> "网球运动员费德勒";3233 case FOOTBALL -> "足球运动员C罗";3435 case BASKETBALL -> "篮球运动员詹姆斯";3637 case PINGPANG -> "乒乓球运动员马龙";3839 case UNKNOWN -> throw new IllegalArgumentException("未知");4041 };4243 }4445}

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

1private static String createPlayer(PlayerTypes playerType) {2 3 return switch (playerType) { 4 5 case TENNIS -> "网球运动员费德勒"; 6 7 case FOOTBALL -> "足球运动员C罗"; 8 9 case BASKETBALL,PINGPANG -> "牛逼运动员沉默王二";1011 case UNKNOWN -> throw new IllegalArgumentException("未知");1213 };1415}

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

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

1private static String createPlayer(PlayerTypes playerType) {2 3 return switch (playerType) { 4 5 case TENNIS -> { 6 7 System.out.println("网球"); 8 9 yield "网球运动员费德勒";1011 }1213 case FOOTBALL -> {1415 System.out.println("足球");1617 yield "足球运动员C罗";1819 }2021 case BASKETBALL -> {2223 System.out.println("篮球");2425 yield "篮球运动员詹姆斯";2627 }2829 case PINGPANG -> {3031 System.out.println("乒乓球");3233 yield "乒乓球运动员马龙";3435 }3637 case UNKNOWN -> throw new IllegalArgumentException("未知");3839 };4041}

细心的同学会发现一个之前素未谋面的关键字 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) {2 3 String var10000; 4 5 switch(playerType) { 6 7 case TENNIS: 8 9 System.out.println("网球");1011 var10000 = "网球运动员费德勒";1213 break;1415 case FOOTBALL:1617 System.out.println("足球");1819 var10000 = "足球运动员C罗";2021 break;2223 case BASKETBALL:2425 System.out.println("篮球");2627 var10000 = "篮球运动员詹姆斯";2829 break;3031 case PINGPANG:3233 System.out.println("乒乓球");3435 var10000 = "乒乓球运动员马龙";3637 break;3839 case UNKNOWN:4041 throw new IllegalArgumentException("未知");4243 default:4445 throw new IncompatibleClassChangeError();4647 }48495051 return var10000;5253}

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

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

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

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

原文链接:

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
显示评论内容(3)
  1. 深呼吸i2024-01-22 06:53深呼吸i[广东省网友]203.31.220.74
    大佬都这么说了,我还是要多学习提升技术水平啊!
    顶43踩0
  2. 淡与浓2023-10-31 13:21淡与浓[四川省网友]203.57.247.114
    switch语句虽老土,但也挺好用的啊。
    顶2踩0
  3. 对着天空说爱你2023-08-09 19:49对着天空说爱你[浙江省网友]113.49.88.161
    哎呀,大佬又来秀操作了!
    顶0踩0
相关阅读
数量造句和解释

数量造句和解释

数量shù liàng,名词。近义词有:数目。指事物的多少。李一氓〈阿英文集〉序:电影,是艺术,更加是工艺和科学,数量和质量,不要再那么寒伧了。数量

2023-09-30

揭秘!央视世界杯解说金句的真正作者

揭秘!央视世界杯解说金句的真正作者

精彩的比赛,伴随着洪钢、贺炜、朱晓雨、刘嘉远、曾侃波澜起伏的评论,更显得荡气回肠

2023-06-22

含蓄的表白的句子 句句感人!

含蓄的表白的句子 句句感人!

2 你在想压葡萄牙还是西班牙,而我只想压你

2022-12-21

2020届高三第一次月考考试语文试卷(有答案)

2020届高三第一次月考考试语文试卷(有答案)

请在规定的时间内将第I卷和第II卷的答案填写在答题卡上,写在试卷上的答案无效

2023-05-03

对话金簰(系列)丨“英”声而来 “语”你同行

对话金簰(系列)丨“英”声而来 “语”你同行

小编:提到英语,很多学生都对单词很发愁,罗老师,您有什么好的背单词的方法吗?罗老师:在回答这个问题之前,我需要和各位家长及同学们明确的是:不要

2023-11-26