instanceof 的模式匹配(二)
在经过了JEP305(jdk14)和JEP375(jdk15)的两轮预览之后,模式匹配终于迎来了他的交付日期,在2022年发布的JDK16中,伴随着JEP 394的发布,预览结束了,我们来看一下这个特性的结束点到底说了什么。
在这次预览之中,我们看到几个例子,教你如何合理的使用模式匹配。
一、对于equals方法的优化
在我们之前的例子我们存在一个问题就是,如果我们要实现Point类的equals方法的时候。比如存在如下代码。
public class Point {private int x;private int y;public Point(int x, int y) {this.x = x;this.y = y;}public final boolean equals(Object o) {if (!(o instanceof Point))return false;Point other = (Point) o;return x == other.x&& y == other.y;}
}
我们着重来看equals方法,我们来分析一下这段代码,他的逻辑就是判断一个对象类型是不是Point,如果不是,直接返回false,如果是,就强转,然后执行后面的比较逻辑。
那么我们其实是可以使用模式匹配来优化这段代码的。很自然的可以优化为如下代码:
.....
public final boolean equals(Object o) {if (o instanceof Point other) {return x == other.x && y == other.y;} else {return false;}
}
我们使用模式匹配把检查转换赋值三步合并起来了。这样就优化了很多,代码变得很简洁。
可是我们在回忆一下,我们在instanceof 的模式匹配(一)中分析过他的这个赋值变量的作用域。我们知道作用域是和模式匹配的判断绑定的。当你模式匹配是true的时候,这个绑定是生效的。
在我们这个例子中,也就是说当o instanceof Point other为true的时候,other可以在分支内使用。那我进一步演化。
public final boolean equals(Object o) {return (o instanceof Point other) && x == other.x && y == other.y;
}
当(o instanceof Point other)为真的时候,后面是可以和other匹配比对的。所以可以生效,不会编译错误。
当(o instanceof Point other)为假的时候,直接返回。false。也是可以生效的。于是这就是模式匹配的最终答案。
而模式变量的流范围分析对语句是否可以正常完成的概念很敏感。例如,请考虑以下方法:
public void onlyForStrings(Object o) throws Exception {if (!(o instanceof String s)) throw new Exception();System.out.println(s);
}
首先他在if不成立的时候使用了绑定变量s,那我们分析一下,此时s能生效吗。if不成立,必然是
o instanceof String s 为真,为真的分支自然是能使用的。所以没问题。我们在使用模式匹配的时候这些问题都是要注意的。不过在现在的ide帮助下,编译错误很容易就提示你修改你的分支作用域。
二、关于局部变量
模式变量只是局部变量的一个特例,除了它们的作用域定义之外,在所有其他方面,模式变量都被视为局部变量。特别是,这意味着 (1) 它们可以被分配给,并且 (2) 它们可以隐藏字段声明。
看着就很晦涩,说的啥玩意,我来给你解读一下,我们来看一段代码:
class Example1 {String s;Example1(String s) {this.s = s;}void test1(Object o) {if (o instanceof String s) {System.out.println("1:" + s);s = s + "helloworld";System.out.println("2:" + s);}System.out.println(s);}
}
简简单单一个代码,没啥好说的。但是我们注意一下,这个类里面有自己的成员变量s我们称之为成员s,同时在test1方法中使用模式匹配,赋值的模式变量也叫s我们称之为模式s。此时会出现一个问题。模式s在自己的作用域范围内是会隐藏成员s。
这一点上他和普通的局部变量不同,因为如果你在test1中定义局部变量是会报错的。

于是我们来调用输出一下结果。
Example1 example1 = new Example1("12");
example1.test1("13");

不出所料,在模式匹配的if分支内部,模式s的13把成员s的12给隐藏了,而在模式匹配的if分支之外。s才能引用到成员变量s的12.
我们再来看这段代码。
class Example2 {Point p;void test2(Object o) {if (o instanceof Point p) {// p 这个if内部,模式匹配为真,模式变量生效,此时发生隐藏,所有的p指的都是模式变量p...} else {// p 这个if内部所有的p指的都是Point p这个成员变量...}}
}
所以很重要的一个注意点就是在使用模式匹配的时候,模式变量的流范围性质意味着必须小心确定名称是引用隐藏字段声明的模式变量声明还是字段声明本身。
至此模式匹配就完成了他的本职工作,但是他的使命还远远没有结束。
未来的JAVA 将通过更丰富的模式形式来增强,例如记录类的析构模式,以及其他语言结构(如 switch 表达式和语句)的模式匹配。
模式匹配还会和其他的语法特征结合起来,表达更加丰富简洁的语义。我们下期见。
相关文章:
instanceof 的模式匹配(二)
在经过了JEP305(jdk14)和JEP375(jdk15)的两轮预览之后,模式匹配终于迎来了他的交付日期,在2022年发布的JDK16中,伴随着JEP 394的发布,预览结束了,我们来看一下这个特性的结束点到底说了什么。 在这次预览之中ÿ…...
【Spring】Bean的作用域和Spring的执行流程
目录 1.Bean的作用域 1.1 Singleton(单例) 1.2 Prototype(原型) 1.3 适用于SpringMVC的作用域 2.Spring的执行流程 2.1 Spring容器的初始化 2.2 Bean的创建和装配 2.3 Bean的生命周期管理 2.4 其他重要概念 3. Spring的执行流程简洁版 1.Bean的作用域 Spring Bean的…...
自动驾驶系列—从数据采集到存储:解密自动驾驶传感器数据采集盒子的关键技术
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
QtWebServer
QtWebServer 是创建基于 Qt 的高性能 Web 应用程序服务器的尝试,即。运行本机 C/Qt 代码以交付网站的 Web 服务器。 一个完美的用例是为较小的服务提供 REST API。 在 Qt 应用程序中,您可以设置资源并将其绑定到物理提供程序,例如文件或数据…...
网络基础概念与应用:深入理解计算机网络
引言 计算机网络作为现代信息技术的重要支柱,是连接世界各地的重要纽带。它使得计算机能够相互通信、协同工作,从而极大地提高了我们的工作效率和生活质量。本篇文章将深入探讨计算机网络的基础概念,覆盖网络的分层模型、协议、数据传输原理…...
<el-select> :remote-method用法
el-select :remote-method用法 说明代码实现单选多选 说明 在 Vue.js 中, 是 Element UI 库提供的一个下拉选择框组件。:remote-method 是 组件的一个属性,用于指定一个远程方法,该方法将在用户输入时被调用,以获取下拉列表的选项…...
CKA认证 | Day3 K8s管理应用生命周期(上)
第四章 应用程序生命周期管理(上) 1、在Kubernetes中部署应用流程 1.1 使用Deployment部署Java应用 在 Kubernetes 中,Deployment 是一种控制器,用于管理 Pod 的部署和更新。以下是使用 Deployment 部署 Java 应用的步骤&#x…...
JavaWeb——HTML、CSS
目录 1.概述 2.HTML a.HTML结构标签 b.图片标签 c.标题标签 d.水平线标签 e.布局标签 f.超链接标签 e.视频标签 f.音频标签 e.换行标签 f.段落标签 g.加粗标签 h.表格 1.声明表格 2.表行 3.普通表格 4.加粗表格 i.表单标签 1.声明表单 2. 表单 3.下拉列表…...
springboot如何获取控制层get和Post入参
一、在 Spring 配置中创建一个过滤器,将 HttpServletRequest 包装为 ContentCachingRequestWrapper import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import j…...
30 秒!用通义灵码画 SpaceX 星链发射流程图
不想读前人“骨灰级”代码, 不想当“牛马”程序员, 想像看图片一样快速读复杂代码和架构? 来了,灵码又加新 buff!! 通义灵码支持代码逻辑可视化, 可以把你的每段代码画成流程图。 你可以把…...
设计模式之组合模式(营销差异化人群发券,决策树引擎搭建场景)
前言: 往往很多大需求都是通过增删改查堆出来的,今天要一个需求if一下,明天加个内容else扩展一下。日积月累需求也就越来越大,扩展和维护的成本也就越来越高。往往大部分研发是不具备产品思维和整体业务需求导向的,总以…...
关于做完 C# 项目的问题总结
1. .Any()方法使用 可以与其他LINQ方法结合使用,以构建更复杂的查询。例如,你可以首先过滤集合,然后检查过滤后的集合是否包含任何元素: List<string> fruits new List<string> { "Apple", "Banana&q…...
CSS响应式布局实现1920屏幕1rem等于100px
代码解析与实现 设置根元素的 font-size 为 5.208333vw 假设你想让根元素的 font-size 基于视口宽度来动态调整。我们可以通过设置 font-size 为 5.208333vw 来让 1rem 相当于视口宽度的 5.208333%。 计算 5.208333vw: 当屏幕宽度为 1920px 时,5.208333vw 等于 5…...
根据当前浏览器版本,下载或更新驱动文件为对应的版本
以前通过ChromeDriverManager().install()的方式自动下载驱动的方式,现在行不通了,访问不通下载网址,会报错:requests.exceptions.ConnectionError: Could not reach host. Are you offline? 所以想着换一个下载地址和方式&…...
【轻量化】YOLOv10 更换骨干网络之 MobileNetv4 | 模块化加法!非 timm 包!
之前咱们在这个文章中讲了timm包的加法,不少同学反馈要模块化的加法,那么这篇就讲解下模块化的加法,值得注意的是,这样改加载不了mobilebnetv4官方开源的权重了~ 论文地址:https://arxiv.org/pdf/2404.10518 代码地址:https://github.com/tensorflow/models/blob/master…...
人体存在感应器设置时间开启感应人存在开灯,失效
环境: 领普人体存在感应器 问题描述: 人体存在感应器设置时间开启感应人存在开灯,失效,设置下午5点,如果有人在5点前一直在这个区域,这个时候到了5点,就触发不了感应自动打开灯光。 解决方案:…...
2024年09月CCF-GESP编程能力等级认证Python编程二级真题解析
本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 据有关资料,山东大学于1972年研制成功DJL-1计算机,并于1973年投入运行,其综合性能居当时全国第三位。DJL-1计算机运算控…...
Vuex vs Pinia:新一代Vue状态管理方案对比
引言 随着Vue生态系统的不断发展,状态管理已经成为现代Vue应用程序中不可或缺的一部分。Vuex作为Vue官方的状态管理方案,一直是开发者的首选。然而,随着Pinia的出现,为Vue开发者带来了新的选择。本文将深入对比这两个状态管理方案…...
es查询报错:too_many_buckets_exception
故障排除 es查询报错:too_many_buckets_exception {"error":{"root_cause":[],"type":"search_phase_execution_exception","reason":"","phase":"fetch","grouped":…...
outlook邮箱关闭垃圾邮件——PowerAutomate自动化任务
微软邮箱反垃圾已经很强大了非常敏感,自家的域名的邮件都能给扔到垃圾邮箱里,但还是在本地增加了一层垃圾邮箱功能,然后垃圾邮箱并没有提示,导致错过很多通知,本身并没有提供关闭的功能,但微软有个Microsof…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
2025.6.9总结(利与弊)
凡事都有两面性。在大厂上班也不例外。今天找开发定位问题,从一个接口人不断溯源到另一个 接口人。有时候,不知道是谁的责任填。将工作内容分的很细,每个人负责其中的一小块。我清楚的意识到,自己就是个可以随时替换的螺丝钉&…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
StarRocks 全面向量化执行引擎深度解析
StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计,相比传统行式处理引擎(如MySQL),性能可提升 5-10倍。以下是分层拆解: 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...
