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

本文探讨了一位开发者对于老式switch语句的吐槽,介绍了Java 12及以上版本中switch语句的新特性,如返回值处理、Lambda表达式和枚举类型检查。作者通过实例展示了如何将代码转换为更简洁、智能的switch表达式,同时讨论了代码风格和兼容性的平衡问题。
摘要由CSDN通过智能技术生成

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

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

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

1privatestaticString createPlayer(PlayerTypes playerType){

2switch(playerType) {

3caseTENNIS:

4return"网球运动员费德勒";

5caseFOOTBALL:

6return"足球运动员C罗";

7caseBASKETBALL:

8return"篮球运动员詹姆斯";

9caseUNKNOWN:

10thrownewIllegalArgumentException( "未知");

11default:

12thrownewIllegalArgumentException(

13"运动员类型: "+ playerType);

14

15}

16}

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

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

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

9d8030ebf77febf627a7f5d1f5aa913e.png

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

1privatestaticString createPlayer( PlayerTypes playerType){

2String player = null;

3switch(playerType) {

4caseTENNIS:

5player = "网球运动员费德勒";

6break;

7caseFOOTBALL:

8player = "足球运动员C罗";

9break;

10caseBASKETBALL:

11player = "篮球运动员詹姆斯";

12break;

13caseUNKNOWN:

14thrownewIllegalArgumentException( "未知");

15}

16

17returnplayer;

18}

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

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

1privatestaticString createPlayer(PlayerTypes playerType) {

2

3returnswitch(playerType) {

4

5caseTENNIS -> "网球运动员费德勒";

6

7caseFOOTBALL -> "足球运动员C罗";

8

9caseBASKETBALL -> "篮球运动员詹姆斯";

10

11caseUNKNOWN -> throw new IllegalArgumentException( "未知");

12

13};

14

15}

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

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

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

1publicenumPlayerTypes {

2

3TENNIS,

4

5FOOTBALL,

6

7BASKETBALL,

8

9PINGPANG,

10

11UNKNOWN

12

13}

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

6b26fbe3421c64b4d91767f3aad013fc.png

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

1publicclassOldSwitchDemo{

2

3publicenumPlayerTypes {

4

5TENNIS,

6

7FOOTBALL,

8

9BASKETBALL,

10

11PINGPANG,

12

13UNKNOWN

14

15}

16

17

18

19publicstaticvoidmain( String[] args){

20

21System. out.println(createPlayer(PlayerTypes.BASKETBALL));

22

23}

24

25

26

27privatestaticString createPlayer( PlayerTypes playerType){

28

29returnswitch(playerType) {

30

31caseTENNIS -> "网球运动员费德勒";

32

33caseFOOTBALL -> "足球运动员C罗";

34

35caseBASKETBALL -> "篮球运动员詹姆斯";

36

37casePINGPANG -> "乒乓球运动员马龙";

38

39caseUNKNOWN -> thrownewIllegalArgumentException( "未知");

40

41};

42

43}

44

45}

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

1privatestaticString createPlayer(PlayerTypes playerType) {

2

3returnswitch(playerType) {

4

5caseTENNIS -> "网球运动员费德勒";

6

7caseFOOTBALL -> "足球运动员C罗";

8

9caseBASKETBALL,PINGPANG -> "牛逼运动员沉默王二";

10

11caseUNKNOWN -> throw new IllegalArgumentException( "未知");

12

13};

14

15}

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

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

1privatestaticString createPlayer( PlayerTypes playerType){

2

3returnswitch(playerType) {

4

5caseTENNIS -> {

6

7System. out.println( "网球");

8

9yield"网球运动员费德勒";

10

11}

12

13caseFOOTBALL -> {

14

15System. out.println( "足球");

16

17yield"足球运动员C罗";

18

19}

20

21caseBASKETBALL -> {

22

23System. out.println( "篮球");

24

25yield"篮球运动员詹姆斯";

26

27}

28

29casePINGPANG -> {

30

31System. out.println( "乒乓球");

32

33yield"乒乓球运动员马龙";

34

35}

36

37caseUNKNOWN -> thrownewIllegalArgumentException( "未知");

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 关键字,我们可以反编译一下字节码:

1privatestaticString createPlayer( NewSwitchDemo3.PlayerTypes playerType){

2

3String var10000;

4

5switch(playerType) {

6

7caseTENNIS:

8

9System. out.println( "网球");

10

11var10000 = "网球运动员费德勒";

12

13break;

14

15caseFOOTBALL:

16

17System. out.println( "足球");

18

19var10000 = "足球运动员C罗";

20

21break;

22

23caseBASKETBALL:

24

25System. out.println( "篮球");

26

27var10000 = "篮球运动员詹姆斯";

28

29break;

30

31casePINGPANG:

32

33System. out.println( "乒乓球");

34

35var10000 = "乒乓球运动员马龙";

36

37break;

38

39caseUNKNOWN:

40

41thrownewIllegalArgumentException( "未知");

42

43default:

44

45thrownewIncompatibleClassChangeError;

46

47}

48

49

50

51returnvar10000;

52

53}

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

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

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

好了,我亲爱的读者朋友,以上就是本文的全部内容了,希望你学得开心。返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值