Java各个版本的switch表达式

文章目录

  • 传统switch声明语句的弊端:
  • JDK12中预览特性:
  • JDK13
  • **JDK17的预览特性:switch的模式匹配**

传统switch声明语句的弊端:

  • 匹配是自上而下的,如果忘记写break,后面的case语句不论匹配与否都会执行; —>case穿透
  • 所有的case语句共用一个块范围,在不同的case语句定义的变量名不能重复;
  • 不能在一个case里写多个执行结果一致的条件;
  • 整个switch不能作为表达式返回值;
//常见错误实现
switch(month){case 3|4|5://3|4|5 用了位运算符,11 | 100 | 101结果是 1117System.out.println("春季");break;case 6|7|8://6|7|8用了位运算符,110 | 111 | 1000结果是111115System.out.println("夏季");break;case 9|10|11://9|10|11用了位运算符,1001 | 1010 | 1011结果是101111System.out.println("秋季");break;case 12|1|2://12|1|2 用了位运算符,1100 | 1 | 10 结果是1111,是15System.out.println("冬季");break;default:System.out.println("输入有误");
}

JDK12中预览特性:

  • Java 12将会对switch声明语句进行扩展,使用case L ->来替代以前的break;,省去了 break 语句,避免了因少写 break 而出错。

  • 同时将多个 case 合并到一行,显得简洁、清晰,也更加优雅的表达逻辑分支。

  • 为了保持兼容性,case 条件语句中依然可以使用字符 : ,但是同一个 switch 结构里不能混用 -> : ,否则编译错误。

举例:

Java 12之前


public class SwitchTest {public static void main(String[] args) {int numberOfLetters;Fruit fruit = Fruit.APPLE;switch (fruit) {case PEAR:numberOfLetters = 4;break;case APPLE:case GRAPE:case MANGO:numberOfLetters = 5;break;case ORANGE:case PAPAYA:numberOfLetters = 6;break;default:throw new IllegalStateException("No Such Fruit:" + fruit);}System.out.println(numberOfLetters);}
}
enum Fruit {PEAR, APPLE, GRAPE, MANGO, ORANGE, PAPAYA;
}

switch 语句如果漏写了一个 break,那么逻辑往往就跑偏了,这种方式既繁琐,又容易出错。

Java 12中:


public class SwitchTest1 {public static void main(String[] args) {Fruit fruit = Fruit.GRAPE;switch(fruit){case PEAR -> System.out.println(4);case APPLE,MANGO,GRAPE -> System.out.println(5);case ORANGE,PAPAYA -> System.out.println(6);default -> throw new IllegalStateException("No Such Fruit:" + fruit);};}
}

更进一步:


public class SwitchTest2 {public static void main(String[] args) {Fruit fruit = Fruit.GRAPE;int numberOfLetters = switch(fruit){case PEAR -> 4;case APPLE,MANGO,GRAPE -> 5;case ORANGE,PAPAYA -> 6;default -> throw new IllegalStateException("No Such Fruit:" + fruit);};System.out.println(numberOfLetters);}
}

JDK13

JDK13中引入了yield语句,用于返回值。这意味着,switch表达式(返回值)应该使用yield,switch语句(不返回值)应该使用break。

yield和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
在以前:

@Test
public void testSwitch1(){String x = "3";int i;switch (x) {case "1":i=1;break;case "2":i=2;break;default:i = x.length();break;}System.out.println(i);
}

在JDK13中:

@Test
public void testSwitch2(){String x = "3";int i = switch (x) {case "1" -> 1;case "2" -> 2;default -> {yield 3;}};System.out.println(i);
}

或者

@Test
public void testSwitch3() {String x = "3";int i = switch (x) {case "1":yield 1;case "2":yield 2;default:yield 3;};System.out.println(i);
}

JDK17的预览特性:switch的模式匹配

旧写法:

static String formatter(Object o) {String formatted = "unknown";if (o instanceof Integer i) {formatted = String.format("int %d", i);} else if (o instanceof Long l) {formatted = String.format("long %d", l);} else if (o instanceof Double d) {formatted = String.format("double %f", d);} else if (o instanceof String s) {formatted = String.format("String %s", s);}return formatted;
}

模式匹配新写法:

static String formatterPatternSwitch(Object o) {return switch (o) {case Integer i -> String.format("int %d", i);case Long l    -> String.format("long %d", l);case Double d  -> String.format("double %f", d);case String s  -> String.format("String %s", s);default        -> o.toString();};
}

直接在 switch 上支持 Object 类型,这就等于同时支持多种类型,使用模式匹配得到具体类型,大大简化了语法量,这个功能很实用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/31327.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

篇十五:模板方法模式:固定算法的步骤

篇十五:"模板方法模式:固定算法的步骤" 设计模式是软件开发中的重要知识,模板方法模式(Template Method Pattern)是一种行为型设计模式,用于定义一个算法的骨架,将算法中一些步骤的具…

ubuntu安装docker-compose

1.官方安装链接 访问:https://docs.docker.com/compose/install/standalone/ 链接,可以看到如下页面,使用下面圈起来的命令即可 2.安装 使用该命令进行安装,很慢,一直卡着不动,原因是从github中下载&am…

路由导航守卫中document.title = to.meta.title的作用以及路由跳转修改页面title

目录 🔽 document.title to.meta.title的作用 🔽 Vue路由跳转时如何更改页面title 🔽 document.title to.meta.title的作用 路由导航守卫如下: router.beforeEach(async (to, from, next) > {document.title to.meta.ti…

MySQL 手机选号(AABB、ABCD、DCBA、AAA),SQL SERVER 手机选号(AABB、ABCD、DCBA、AAA),通过规则查询靓号

先上SQL SERVER: create table plat_uidlist(Uidd varchar(15) , Areaid int , State int)insert into plat_uidlist values(2335435 ,8 ,0 ) insert into plat_uidlist values(2335436 ,8 ,1 ) insert into plat_uidlist values(2335437 ,2 ,2 ) insert into plat…

css中的var函数

css中的var函数 假设我们在css文件存在多个相同颜色值,当css文件越来越大的时候,想要改颜色就要手动在每个旧颜色上修改,这样维护工作非常难进行。 但是我们可以使用变量来存储值,这样可以在整个css样式表中重复使用&#xff0c…

HarmonyOS/OpenHarmony应用开发-ArkTS语言渲染控制概述

ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。 在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助UI的构建,这些渲染控制语句包括控制组件是否显示的条件渲染语句,基于数组数…

【区块链】Go 实现简单区块链

本文主要利用 Go 语言对区块链模型进行了简单的实现,通过 GoLand 创建链式结构和一个简单的 http server,对外暴露读写接口,运行 rpc 并以地址访问形式向区块链发送数据和读取数据。 简单区块链的实现大致步骤分为: (…

【并发编程】线程池多线程异步去分页调用其他服务接口获取海量数据

文章目录 场景:解决方案 场景: 前段时间在做一个数据同步工具,其中一个服务的任务是调用A服务的接口,将数据库中指定数据请求过来,交给kafka去判断哪些数据是需要新增,哪些数据是需要修改的。 刚开始的设…

【Docker】配置指定大小的磁盘空间

背景 测试磁盘满时程序的运行情况 问题 如何使用 docker 来模拟磁盘满的情况 解决方法 创建指定大小的数据卷 volumedocker volume create --driver local --opt typetmpfs --opt devicetmpfs --opt osize50M my_volumn创建 docker 时,使用该数据卷docker run …

JS逆向系列之猿人学爬虫第14题-备而后动-勿使有变

文章目录 题目地址参数分析参考jspython 调用往期逆向文章推荐题目地址 https://match.yuanrenxue.cn/match/14题目难度标的是困难,主要难在js混淆部分。 参数分析 初始抓包有无限debugger反调试,可以直接hook 函数构造器过掉无限debugger Function.prototype.__construc…

Mirror网络库 | 说明

此篇为上文,下篇:Mirror网络库 | 实战 一、介绍 基于UNET,从2014年经过9年实战测试;服务器和客户端是一个项目;使用NetworkBehaviour而不是MonoBehaviour,还有NetworkServer和NetworkClient;Mi…

pdf怎么压缩到1m?这样做压缩率高!

PDF是目前使用率比较高的一种文档格式,因为它具有很高的安全性,还易于传输等,但有时候当文件体积过大时,会给我们带来不便,这时候简单的解决方法就是将其压缩变小。 想要将PDF文件压缩到1M,也要根据具体的情…

雅克比矩阵在机器人运动学中的应用

以六轴机械臂为例,设机械臂关节空间为q,位置矩阵为p,速度矩阵为v q [ q 0 , q 1 , q 2 , q 3 , q 4 , q 5 ] q[q_0,q_1,q_2,q_3,q_4,q_5] q[q0​,q1​,q2​,q3​,q4​,q5​] p [ x , y , z ] T [ f x ( q ) f y ( q ) f z ( q ) ] p[x,y,z…

ASP.NET Core中间件记录管道图和内置中间件

管道记录 下图显示了 ASP.NET Core MVC 和 Razor Pages 应用程序的完整请求处理管道 中间件组件在文件中添加的顺序Program.cs定义了请求时调用中间件组件的顺序以及响应的相反顺序。该顺序对于安全性、性能和功能至关重要。 内置中间件记录 内置中间件原文翻译MiddlewareDe…

微服务 云原生:基于 Gogs + Drone 实现 CI/CD 自动化

一般构建部署 以一个简单的前后端项目来说,分别编写前后端的 Dockerfile 文件并构建镜像,然后编写 docker-compose.yml 构建部署,启动运行。每次代码变更后都需重新手动打包、构建、推送。 一个简单的例子: 前端: 项…

【力扣每日一题】2023.8.7 反转字符串

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个字符数组形式的字符串,让我们直接原地修改反转字符串,不必返回。 给出的条件是使用O(1)的额外空间…

bash: sudo: command not found的解决方法 | 安装sudo

-bash: sudo: command not found的解决方法 https://www.cnblogs.com/pengpengboshi/p/16159443.html 报错 安装apt-get update报错由于没有公钥,无法验证下列签名: NO_PUBKEY A4B469963BF863CC解决办法是手动加入 (sudo可去掉)…

c# 全网最稳定 企业级 以太网客户端类库 具备即时更新状态,断线三次重拨,稳定收发。

源码下载,带示例 代码实现了一个基本的TCP客户端,能够连接到服务器并发送接收数据。当连接失败时,会进行重连,并在达到最大重连次数后终止连接。使用异步编程模型、实现事件模型以及重连机制。 ConnectAsync(): 这是一个异步方法,用于与服务器建立连接。在方法中,首先初始…

ARM架构银河麒麟docker,源码编译安装GDAL

docker中安装依赖 sudo apt-get update sudo apt-get install build-essential autoconf automake libtool sudo apt-get install libproj-dev libgeos-dev libjson-c-dev libpng-dev libjpeg-dev sudo apt-get install python3-dev sudo apt-get install python3.11-dev去官网…

IO密集时epoll还高效吗?

io特别密集时为什么 epoll 效率不高。原因是: 连接密集(短连接特别多),使用epoll的话,每一次连接需要发生epoll_wait->accpet->epoll_ctl调用,而使用select只需要select->accpet,减少了…