51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

switch 都支持null了,难道客官还不进来看看! Java17新特性(预览)尝鲜之switch万剑齐发 --20210811

曾几何时指北君去面试的时候,一些面试官老是问 switch 支持 String 麽之类的问题。 如今指北君想拍案而起,不要在问了,Java 中的 switch 都快支持到银河系了。什么null,Object... ...等等, 已经全部支持! 下面指北君带大家看看万箭齐发的switch到底有多强。

没搞错,就是时代新贵 Java17 推出的新特性喽。虽然暂时还没有完全发布,而且是预览特性。但我们还是可以玩一玩这个飞出天际线的switch!

1. 上第一道菜 "白切贵妃鸡"垫垫肚子- switch语句的一般用法 {#1-上第一道菜-白切贵妃鸡垫垫肚子--switch语句的一般用法}

img

第一道菜,我们来一个白切贵妃鸡(白切的,不要钱): 话不多说我们看看switch的普通用法,

|---------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public static void main(String[] args) { 上菜(菜系.粤菜); } enum 菜系{ 川菜,鲁菜,粤菜,苏菜,浙菜,闽菜,湘菜,徽菜 } private static void 上菜(菜系 菜) { String 出菜 = "空盘子"; switch (菜) { case 川菜: 出菜 = "水煮肉片"; break; case 鲁菜: 出菜 = "九转大肠"; break; case 粤菜: 出菜 = "白切贵妃鸡"; break; case 苏菜: 出菜 = "水晶肴肉"; break; case 浙菜: 出菜 = "西湖醋鱼"; break; case 闽菜: 出菜 = "扳指干贝"; break; case 湘菜: 出菜 = "霸王别姬"; break; case 徽菜: 出菜 = "当归獐肉"; break; default: throw new RuntimeException("没有菜了,陕菜来一个?"); } System.out.println("客官,你要的:" + 出菜 +" 尽情品尝!"); System.out.println("如果菜品满意,请客官素质三连!跪谢!"); } |

代码中变量名使用了中文,只是为了让各位看官们不那么枯燥,顺便了解一下八大菜系。(编译需指定UTF-8字符集)

客官,白切的贵妃鸡好吃么,那么请结账: 此处由 店小二 Java12 为您服务。

|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | enum 指北君特色菜{ 水煮肉片,白切贵妃鸡,水晶肴肉,扳指干贝,九转大肠,西湖醋鱼,霸王别姬,当归獐肉,凉皮肉夹馍 } private static void 结账(指北君特色菜 特色菜) { var 菜价 = switch (特色菜) { case 水煮肉片 -> 10000; case 白切贵妃鸡,水晶肴肉 -> 20000; case 扳指干贝,九转大肠,西湖醋鱼 -> 30000; case 霸王别姬,当归獐肉 -> 40000; case 凉皮肉夹馍 -> 15; default -> throw new RuntimeException("客官,你吃了空气,免费!"); }; System.out.println("店小二Java12 :客官,您好! 您点的 "+特色菜 + " 价值"+ 菜价/10000 + "万元人名币"); } |

连break都省了,结账块多了呢!

2. 客官吃了 白切的贵妃鸡,胃口大开,再点了 西湖醋鱼 {#2-客官吃了-白切的贵妃鸡胃口大开再点了-西湖醋鱼}

xihucuyu

客官没吃爽,又点了西湖醋鱼。吃完菜又该结账了,店小二忙不开,请来了好徒弟 Java 14帮忙。

|------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | private static void 小14结账(指北君特色菜 特色菜) { var 菜价 = switch (特色菜) { case 水煮肉片 -> 10000; case 白切贵妃鸡,水晶肴肉 -> 20000; case 扳指干贝,九转大肠,西湖醋鱼 -> { System.out.println("客官 :好吃好吃,指北君特色菜果然好吃 !!!"); yield 30000; } case 霸王别姬,当归獐肉 -> 40000; case 凉皮肉夹馍 -> { System.out.println("客官 : 好吃好吃,还是凉皮肉夹馍经济实惠又好吃 !!!"); yield 15; } default -> throw new RuntimeException("客官,你吃了空气,免费!"); }; System.out.println("店小二Java14 : 客官,您好! 您点的 "+特色菜 + " 价值"+ 菜价/10000 + "万元人名币"); } |

yield 返回菜价,掏空你的钱包。

3 客官用餐完毕,菜馆需要总结经验 - switch 在Java17 中如何使用。 {#3--客官用餐完毕菜馆需要总结经验---switch-在java17-中如何使用}

盘点的时候看看客人吃了那些菜 ,爱吃那些菜系。 Java 17 预览小哥为您服务。请看小二如何统计。

|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | enum 川菜{ 水煮肉片,麻婆豆腐,夫妻肺片 } enum 湘菜{ 水煮肉片,麻婆豆腐,夫妻肺片 } enum 浙菜{ 西湖醋鱼,红烧狮子头,醉虾 } staticvoid客户用餐总结(Objecto){switch(o){casenull->System.out.println("顾客喝了西北风,但是还是钟爱Java技术指北");case浙菜z->System.out.println("顾客爱吃浙菜");case湘菜x->System.out.println("顾客以爱吃湘菜");caseStrings->System.out.println("客官重口味,爱吃川菜");default->System.out.println("客户啥都吃,也爱Java技术指北!");};} |

Java 17 中预览版switch支持null 以及 Object 为switch中的参数,相当于在case中使用了: xxx instance of 这样的语句。

由于Switch的一些功能在Java17中暂时只是预览,如果需要使用,那么在编译的时候就需要加上 --enable-preview 的参数,具体编译代码如下。

|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 | openjdk-17-ea+26_windows-x64_bin\jdk-17\bin>javac --enable-preview -source 17 -encoding utf-8 SwitchTest.javaopenjdk-17-ea+26_windows-x64_bin\jdk-17\bin>javac --enable-preview -source 17 -encoding utf-8 SwitchTest.java |

执行时也要启用预览功能:

|-----------|----------------------------------| | 1 | java --enable-preview SwitchTest |

4 盘点Java 17 中的 switch {#4-盘点java-17-中的-switch}

4.1 支持了switch 类型检查case {#41-支持了switch-类型检查case}

示例如下

|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 | record Point(int i, int j) {} enum Color { RED, GREEN, BLUE; } staticvoidtypeTester(Objecto){switch(o){casenull->System.out.println("null");caseStrings->System.out.println("String");caseColorc->System.out.println("Color with "+c.values().length+" values");casePointp->System.out.println("Record class: "+p.toString());caseint[]ia->System.out.println("Array of ints of length"+ia.length);default->System.out.println("Something else");}} |

switch 中的参数使用Object, case 匹配各种类型,实则是一种类似于 instence of 的更简单的写法!

4.2 完善了switch表达式以及语句操作 {#42-完善了switch表达式以及语句操作}

例如下面:

|------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static void booleanSwitchTest(Object o){ boolean b = false; String test = "" ; switch (o) { case String s && b -> test = "很帅"; case String s -> test = "很酷"; default -> test = "很可爱"; } System.out.println("Java技术指北" + test); } booleanSwitchTest("很有趣");//调用方法得到 "Java技术指北很酷" |

可以直接返回语句处理结果。

4.3 switch case 变量的范围扩大 {#43-switch-case-变量的范围扩大}

如果switch参数为接口或者类,则可以在case中匹配其子类,或者实现类。也可以参考上文4.1中的例子!

4.4 可以处理null的情况 {#44-可以处理null的情况}

case中可以对null进行判断处理,前面的示例中已经包含了相关操作,此特性请参考上文4.1种的例子!

总结 {#总结}

  • Java 17 中的 switch 预览版包含了大致4种switch的增强

    1. 增强了类型检查。
    2. 完善了 switch表达式 以及表达式后的语句逻辑处理。
    3. switch case 变量的范围扩大
    4. null值的处理。
  • 从JEP 406 中的未来展望可以看出,此刻switch还不支持基本类型中的boolean,float,double,但是将来肯定会找到更合适的解决方案,让switch能支持全Java系列。

  • switch支持的解决方案越多,对于开发者来说能省掉很多的代码,间接的提高工作效率,提高程序的性能。期待未来的某一天switch的火力全开版本正式发布,那一天你还会看到 Java技术指北 的再一次更全面的解说。

赞(1)
未经允许不得转载:工具盒子 » switch 都支持null了,难道客官还不进来看看! Java17新特性(预览)尝鲜之switch万剑齐发 --20210811