我去,你写的 switch 语句也太老土了吧
点击上方“方志朋”,选择“设为星标”
回复”666“获取新整理的面试文章
昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!”
来看看小王写的代码吧,看完不要骂我装逼啊。
private static String createPlayer(PlayerTypes playerType) {switch (playerType) {case TENNIS:return "网球运动员费德勒";case FOOTBALL:return "足球运动员C罗";case BASKETBALL:return "篮球运动员詹姆斯";case UNKNOWN:throw new IllegalArgumentException("未知");default:throw new IllegalArgumentException("运动员类型: " + playerType);}
}
看完上述代码后,你是不是会发出这样的感慨——“代码写得很好,没有任何问题啊!”是不是觉得我在无事生非,错怪了小王!但此时我要送上《了不起的盖茨比》中的一句话:
我年纪还轻,阅历不深的时候,我父亲教导过我一句话,我至今还念念不忘。“每逢你想要批评任何人的时候, ”他对我说,“你就记住,这个世界上所有的人,并不是个个都有过你拥有的那些优越条件。”
哈哈,这句话不光是让你看的,也是给我看的。是时候冷静下来谈谈上述 switch 语句的老土问题了。
看到上图了吧,当不小心删掉 default 语句后,编译器就会报错,提示:“没有返回语句”,为了解决这个问题,我们可以新建一个 player 变量作为返回结果,就像下面这样:
private static String createPlayer(PlayerTypes playerType) {String player = null;switch (playerType) {case TENNIS:player = "网球运动员费德勒";break;case FOOTBALL:player = "足球运动员C罗";break;case BASKETBALL:player = "篮球运动员詹姆斯";break;case UNKNOWN:throw new IllegalArgumentException("未知");}return player;
}
当添加了 player 变量后,case 语句中就需要添加上 break 关键字;另外在 switch 语句结束后,返回 player。这时候,编译器并不会提示任何错误,说明 default 语句在这种情况下是可以省略的。
从 JDK 12 开始(本例使用的是 JDK 13),switch 语句升级了,不仅可以像传统的 switch 语句那样作为条件的判断,还可以直接作为一个返回结果。来对小王的代码进行改造,如下所示:
private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> "网球运动员费德勒";case FOOTBALL -> "足球运动员C罗";case BASKETBALL -> "篮球运动员詹姆斯";case UNKNOWN -> throw new IllegalArgumentException("未知");};
}
够 fashion 吧?不仅 switch 关键字之前加了 return 关键字,case 中还见到了 Lambda 表达式的影子,中划线和箭头替代了冒号,意味着箭头右侧的代码只管执行无须 break。
并且,default 语句变成了可选项,可有可无,不信?你也动手试试。
新的 switch 语句足够的智能化,除了有上述的 3 个优势,还可以对枚举类型的条件进行校验。假如在 PlayerTypes 中增加了新的类型 PINGPANG(乒乓球):
public enum PlayerTypes {TENNIS,FOOTBALL,BASKETBALL,PINGPANG,UNKNOWN
}
此时编译器会发出以下警告:
意思就是 switch 中的 case 条件没有完全覆盖枚举中可能存在的值。好吧,那就把 PINGPANG 的条件加上吧。来看一下完整的代码:
public class OldSwitchDemo {public enum PlayerTypes {TENNIS,FOOTBALL,BASKETBALL,PINGPANG,UNKNOWN}public static void main(String[] args) {System.out.println(createPlayer(PlayerTypes.BASKETBALL));}private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> "网球运动员费德勒";case FOOTBALL -> "足球运动员C罗";case BASKETBALL -> "篮球运动员詹姆斯";case PINGPANG -> "乒乓球运动员马龙";case UNKNOWN -> throw new IllegalArgumentException("未知");};}
}
switch 语句变成了强大的 switch 表达式,美滋滋啊!那假如一个运动员既会打篮球又会打乒乓球呢?
private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> "网球运动员费德勒";case FOOTBALL -> "足球运动员C罗";case BASKETBALL,PINGPANG -> "牛逼运动员沉默王二";case UNKNOWN -> throw new IllegalArgumentException("未知");};
}
就像上述代码那样,使用英文逗号“,”把条件分割开就行了,666 啊!
不服气?switch 表达式还有更厉害的,->
右侧还可以是 {}
括起来的代码块,就像 Lambda 表达式那样。
private static String createPlayer(PlayerTypes playerType) {return switch (playerType) {case TENNIS -> {System.out.println("网球");yield "网球运动员费德勒";}case FOOTBALL -> {System.out.println("足球");yield "足球运动员C罗";}case BASKETBALL -> {System.out.println("篮球");yield "篮球运动员詹姆斯";}case PINGPANG -> {System.out.println("乒乓球");yield "乒乓球运动员马龙";}case UNKNOWN -> throw new IllegalArgumentException("未知");};
}
细心的同学会发现一个之前素未谋面的关键字 yield
,它和传统的 return、break 有什么区别呢?
先来看官方的解释:
A yield statement transfers control by causing an enclosing switch expression to produce a specified value.
意思就是说 yield 语句通过使一个封闭的 switch 表达式产生一个指定值来转移控制权。为了进一步地了解 yield
关键字,我们可以反编译一下字节码:
private static String createPlayer(NewSwitchDemo3.PlayerTypes playerType) {String var10000;switch(playerType) {case TENNIS:System.out.println("网球");var10000 = "网球运动员费德勒";break;case FOOTBALL:System.out.println("足球");var10000 = "足球运动员C罗";break;case BASKETBALL:System.out.println("篮球");var10000 = "篮球运动员詹姆斯";break;case PINGPANG:System.out.println("乒乓球");var10000 = "乒乓球运动员马龙";break;case UNKNOWN:throw new IllegalArgumentException("未知");default:throw new IncompatibleClassChangeError();}return var10000;
}
编译器在生成字节码的时候对 yield
关键字做了自动化转义,转成了传统的 break 语句。这下清楚了吧?
但是,话又说出来,那些看似 fashion 的代码也不过是把部分秀技的工作交给了编译器,还可能存在对旧版本不兼容、对队友不友好的问题——代码土点就土点呗,没准是最实用的。
“不好意思,我为昨天早上的嚣张向你道歉。。。。。。”我向小王发送了一条信息。
热门内容:硬核干货:一位码农的架构师封神之路!
阿里问题定位神器 Arthas 的骚操作,定位线上BUG,超给力
用好idea这几款插件,可以帮你少写30%的代码!浅谈 CAP 和 Paxos 共识算法一个丧心病狂的Github项目:东北话编程,大写的服!一位后端妹纸的面试总结(美团+阿里+携程+58+贝贝+招银+华为+....)最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。
我去,你写的 switch 语句也太老土了吧相关推荐
- 技术大佬:我去,你写的 switch 语句也太老土了吧!
作者 | 沉默王二 来源 | CSDN 博客专家 出品 | CSDN(ID:CSDNnews) 昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到 ...
- switch java 语法_Java编程—switch语句语法详解
5.3.2 switch语句 switch关键字的中文意思是开关.转换的意思,switch语句在条件语句中特别适合做一组变量相等的判断,在结构上比if语句要清晰很多. switch语句的语法格式为: ...
- C语言case后语句省略不写,switch语句基础理解与分析
switch语句和if语句最为相似,语法接近C语言. switch(expression) { case value: statement break; case value: state ...
- java写输出春夏秋冬,switch语句之“春夏秋冬”案例
switch语句之春夏秋冬案例 1.功能描述:键盘录入月份,输出对应的季节 2.要求: (1)定义一个月份,值通过键盘录入; (2)输出该月份对应的季节 3,4,5春季 6,7,8夏季 9,10,11 ...
- 精解C++的switch语句
入门书籍对switch语句的介绍相对较浅,我也因此而产生了很多想当然的误解.为解惑而写了以下一小篇精解switch语句,相信会对很多朋友有所帮助,同时顺便补充一些相关知识. 先抛出个题目,见下程序: ...
- 程序实现switch语句判断年龄_【回顾】(选择执行语句if else和switch)乐创DIY C语言讲义——3.8节(4)...
文 | Edward 4 选择执行语句有些时候,我们希望程序既不顺序执行,也不只做单一的判断(代码运行还是不运行),很多时候,我们往往只希望对某一个条件的不同状态分别执行不同的语句,这样就 ...
- C#: switch语句的重构
switch语句是我们日常工作中最常见也是争论最多的(goto被忽视的前提下).在重构中也把switch语句看成是一种代码的坏味道.但如何改造现有的switch代码并在今后去避免呢?本文从两方面进行探 ...
- 【译】为什么我更喜欢对象而不是switch语句
原文自工程师Enmanuel Durán博客,传送门 最近(或者不是最近,这完全取决于您什么时候阅读这边文章),我正在跟我的团队伙伴讨论如何去处理这种需要根据不同的值去处理不同的情况的方法,通常对于这 ...
- c#switch语句判断成绩_C#程序流程控制 知多少?
最近发现读书是个慢过程,很难一口吃个胖子,尤其读这种技术类的书,需要细嚼慢咽的精读,很耐心的读.迄今为止我一个像样的C#程序都没有做过,是小白中的小白,这倒不影响什么,毕竟在曾经学过C语言的,再去学习 ...
最新文章
- 关于ActionBar的向下兼容
- 0.5s c语言延时子程序集,用C语言实现精确的延时.doc
- 服务器是什么系统_服务器自愈路由系统、单线以及BGP多线的区别是什么?
- 基于Jenkins的开发测试全流程持续集成实践
- ckc交易什么意思_在期货交易中,所谓的期货对冲是什么意思?
- 投简历 找工作 App
- 电脑一复制粘贴就卡死_CAD复制粘贴时卡死的解决方法步骤
- msm8953 PWM背光
- 【人工智能项目】LSTM实现数据预测分类实验
- [技术分享 – FCS 篇] 驭龙五式3之飞龙在天:安装 FCS 服务器
- 空气净化器对比测试PM2.5去除效果显著
- 1360: plank 栅栏修复
- ORA-01439: 要更改数据类型, 则要修改的列必须为空
- 如何高效的学习JAVA?
- 如何提取视频中的音频,这个方法真的很简单
- 【Chaos混沌】基于Simulink的Chaos混沌电路设计
- 求解n阶方阵的行列式
- AIEngine 下一代可编程的开源网络入侵检测系统,
- 【移动通信】 01-移动通信概论
- Unix Shell范例精解---grep和sed练习题
热门文章
- 运维基础-文件权限管理
- 2017-02-20 注册.Net Framework4.0
- 使用laravel框架的eloquent\DB模型连接多个数据库
- linux 如何禁用账号和解除禁用账号
- Android Layer List 使用实现实例
- Datawhale组队学习周报(第035周)
- 刻意练习:LeetCode实战 -- Task16. 无重复字符的最长子串
- 【建模必备】遗传算法的基本原理与步骤(交叉)
- 【数据结构】顺序串的插入算法,删除算法,连接运算,顺序串求子串算法
- 老码农90%的程序猿都是瞎努力,这份路线教你成为高手!