写点什么

Record 模式提升了 Java,能实现更具表现力的编码

  • 2023-05-31
    北京
  • 本文字数:1777 字

    阅读完需:约 6 分钟

Record模式提升了Java,能实现更具表现力的编码

摘要:

由于在 JEP 432 和 JEP 405 中进行了反馈驱动的增强,JEP 440,最终确定的记录模式(Record Patterns)已从 JDK 21 从 Proposed to Target 状态提升为 Target 状态。在与类型模式一起使用时,记录模式现在允许进行强大的数据导航和处理。JEP 432 的主要更改是删除了增强 for 语句头中的记录模式。


JDK 21 的 JEP 440,记录模式已从 Proposed to Target 状态提升Targeted 状态。该 JEP 最终确定了这个特性,并结合了增强功能以响应前两轮预览的反馈:JEP 432,记录模式(第二次预览),在 JDK 20 中交付;以及 JEP 405,记录模式(预览),在 JDK 19 中提供。该特性通过记录模式增强了语言以解构记录值。记录模式可以与类型模式结合使用,以“实现一种强大的、声明式的和可组合的数据导航和处理形式”。类型模式最近进行了扩展以用于 switch case 标签:JEP 420,switch模式匹配(第二次预览),在 JDK 18 中提供,以及 JEP 406,switch模式匹配(预览),在 JDK 17 中提供。与 JEP 432 相比,其最重要的更改是删除了对出现在增强for语句头中记录模式的支持。


通过所有这些更改,Java 现在通过引入可嵌套的记录模式,正朝着更具声明式、以数据为中心的编程风格发展。这一演变是在模式匹配与 Java 16 引入的JEP 394instanceof操作符集成之后发生的。

考虑这样一种情况,即你有一个记录Point和一个枚举Color

record Point(int x, int y) {}enum Color { RED, GREEN, BLUE }
复制代码

无论对象是否是record的实例,新的记录模式都允许对其进行测试,并直接解构其组件。例如:

if (r instanceof Rectangle(ColoredPoint ul, ColoredPoint lr)) {    System.out.println(ul.c());}
复制代码

更强大的是它提供了嵌套模式,允许进一步解构record值。考虑如下的声明:

record ColoredPoint(Point p, Color c) {}record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {}
复制代码

如果我们想从左上角提取颜色,可以这样写:

if (r instanceof Rectangle(ColoredPoint(Point p, Color c), ColoredPoint lr)) {    System.out.println(c);}
复制代码

记录模式的这种演变扩展了模式匹配,以解构记录类的实例,从而支持了更复杂的数据查询。无论对象是否是record的实例,它都允许对其进行测试,并直接提取对象的组件。这种方法使代码更加简洁,而且不易出错。考虑如下的示例:

static void printXCoordOfUpperLeftPointWithPatterns(Rectangle r) {    if (r instanceof Rectangle(ColoredPoint(Point(var x, var y), var c),                               var lr)) {        System.out.println("Upper-left corner: " + x);    }}
复制代码

此外,嵌套模式的引入通过提供解构嵌套数据结构的能力,进一步实现了这一点。它们使开发人员能够集中处理错误,因为整个模式只有匹配和不匹配两类。这样就不需要检查和处理每个单独的子模式匹配故障了。

这些嵌套模式也可以很好地与JEP 441引入的switch表达式配合使用。switch表达式的模式匹配增强了switch语句,允许在case标签中使用模式。这使得代码更具表现力,并减少了由于switch语句中的遗漏 case 而导致缺陷的可能性。

例如,考虑以下的声明:

class A {}class B extends A {}sealed interface I permits C, D {}final class C implements I {}final class D implements I {}record Pair<T>(T x, T y) {}
Pair<I> p;
复制代码

使用记录模式和枚举switch,我们可以执行以下操作:

switch (p) {    case Pair<I>(C c, I i) -> ...    case Pair<I>(D d, C c) -> ...    case Pair<I>(D d1, D d2) -> ...}
复制代码

然而,这些更新带来了一些风险和假设。与任何语言的更改一样,其存在影响现有代码库的风险。此外,这些更改假设开发人员熟悉记录类和模式匹配,而这两个特性对 Java 来说相对还较新。


展望未来,有许多方向可以扩展记录模式。其中包括可变变量记录的 varargs 模式、匹配任何值但不声明模式变量的未命名模式,以及可以应用于任意类而不仅仅是记录类的值模式。


总而言之,在 Java 中引入记录和嵌套模式是该语言的一次重大飞跃。它允许更具声明式的编码风格,从而产生更干净、更易于理解的代码。虽然存在一些风险,但潜在的好处能使它成为 Java 未来版本中一个很有前途的特性。


原文链接:

https://www.infoq.com/news/2023/05/java-gets-boost-with-record/


延伸阅读:

JEP 444:JDK 21 中出现虚拟线程,开创并发新纪元

加入有序集合,Java 集合框架变得更加完善

2023-05-31 18:3710983

评论

发布
暂无评论
发现更多内容

系统稳定性建设之我见(64/100)

hackstoic

质量管理 系统稳定性

Django笔记十七之group by 分组用法总结

Hunter熊

Python django count 分组查询 sum

对数据库中存储的程序进行现代化改造,以使用 Amazon Aurora PostgreSQL 联合查询、pg_cron 和 Amazon Lambda

亚马逊云科技 (Amazon Web Services)

来字节跳动实习,有机会发Nature子刊

字节跳动技术范儿

第五期(2022-2023)传统行业云原生技术落地调研报告——金融篇

York

容器 DevOps 微服务 云原生 金融

linux dbus客户端和服务器示例代码

linux大本营

c++ Linux dbus

扎最深的寨,打最持久的仗——一知智能AI商业化攻略访谈录

B Impact

如何建设IT运维流程与体系

穿过生命散发芬芳

运维体系 三周年连更

容量成本性能全都要有, Redis 容量版 PegaDB 设计与实践

百度开发者中心

云数据库 百度智能云

一个有趣的图片加载效果

南城FE

CSS 前端 动画 图片

打工人逃不开「单人单岗」

Java 架构 程序人生 职场

电子签赛道驶向深水区,法大大以数智化引领创新

ToB行业头条

linux dbus代码举例

linux大本营

Linux C++

2022-04-26:给定一个数组componets,长度为A, componets[i] = j,代表i类型的任务需要耗时j 给定一个二维数组orders,长度为M, orders[i][0]代表i

福大大架构师每日一题

golang 算法

一键生成通用的微服务(gRPC)项目代码,让你的开发效率翻倍提升

vison

Go 微服务 gRPC 代码自动生成

概述产品设计通用七原则

阿泽🧸

产品设计 三周年连更

写一个完整的SHOW TABLE STATUS 语句返回的所有表的状态信息对应的结构体

linux大本营

数据库 存储 结构体 C++

解析下rte_pktmbuf_pool_create参数含义

linux大本营

DPDK DPDK开发

重载++运算符分别实现i++和++i

linux大本营

运算符 数据结构与算法

openbmc 中如何使用D-bus

linux大本营

dbus openBMC

一文带你了解实战常用JavaScript API

程序员海军

JavaScript 三周年连更

基于Flutter实现Windows平台离线大模型对话应用实战

轻口味

flutter AI windows 跨平台 三周年连更

什么是Java 异常?如何处理异常?

Java架构历程

Java 三周年连更

UDP报头是通过结构体位段实现的吗

linux大本营

网络协议 udp UDP协议

Go sync.Once:简约而不简单的并发利器

陈明勇

Go golang 高并发 三周年连更 sync.Once

nvim 配置c++环境

linux大本营

vim C++

共话数字化新技术、新趋势 华为云开发者日东莞站成功举办

Geek_2d6073

dpdk中,如何建立portid/queue的配置和逻辑核心的关系

linux大本营

队列 DPDK DPDK开发

如何使用 SCP 和 Rsync 在 Linux 中传输文件

wljslmz

Linux 三周年连更

6G 通信技术和 5G 通信技术的区别

汪子熙

通讯协议 通讯 三周年连更

dpdk l2fwd如何初始化每个逻辑核的port/queue的

linux大本营

队列 DPDK DPDK开发

Record模式提升了Java,能实现更具表现力的编码_语言 & 开发_A N M Bazlur Rahman_InfoQ精选文章