曾几何时指北君去面试的时候,一些面试官老是问 switch 支持 String 麽之类的问题。 如今指北君想拍案而起,不要在问了,Java 中的 switch 都快支持到银河系了。什么null,Object... ...等等, 已经全部支持! 下面指北君带大家看看万箭齐发的switch到底有多强。
没搞错,就是时代新贵 Java17 推出的新特性喽。虽然暂时还没有完全发布,而且是预览特性。但我们还是可以玩一玩这个飞出天际线的switch!
1. 上第一道菜 "白切贵妃鸡"垫垫肚子- switch语句的一般用法 {#1-上第一道菜-白切贵妃鸡垫垫肚子--switch语句的一般用法}
第一道菜,我们来一个白切贵妃鸡(白切的,不要钱): 话不多说我们看看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-客官吃了-白切的贵妃鸡胃口大开再点了-西湖醋鱼}
客官没吃爽,又点了西湖醋鱼。吃完菜又该结账了,店小二忙不开,请来了好徒弟 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
客户用餐总结(Object
o)
{
switch
(o)
{
case
null
->
System.out.println("顾客喝了西北风,但是还是钟爱Java技术指北");
case
浙菜
z
->
System.out.println("顾客爱吃浙菜");
case
湘菜
x
->
System.out.println("顾客以爱吃湘菜");
case
String
s
->
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; } staticvoid
typeTester(Object
o)
{
switch
(o)
{
case
null
->
System.out.println("null");
case
String
s
->
System.out.println("String");
case
Color
c
->
System.out.println("Color with "
+
c.values().length
+
" values");
case
Point
p
->
System.out.println("Record class: "
+
p.toString());
case
int[]
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的增强
- 增强了类型检查。
- 完善了 switch表达式 以及表达式后的语句逻辑处理。
- switch case 变量的范围扩大
- null值的处理。
-
从JEP 406 中的未来展望可以看出,此刻switch还不支持基本类型中的boolean,float,double,但是将来肯定会找到更合适的解决方案,让switch能支持全Java系列。
-
switch支持的解决方案越多,对于开发者来说能省掉很多的代码,间接的提高工作效率,提高程序的性能。期待未来的某一天switch的火力全开版本正式发布,那一天你还会看到 Java技术指北 的再一次更全面的解说。