Java记录类入门:简化的以数据为中心的Java编程

news/2025/12/1 11:24:47/文章来源:https://www.cnblogs.com/icodewalker/p/19292138

记录类声明是一种在Java类中封装数据同时减少样板代码的高效方式。本文将通过基础及高级编程场景介绍其工作原理。

文件柜中的文件记录 图片来源:Stokkete / Shutterstock*

Java记录类是一种用于存储数据的新型类。无需编写构造方法、访问器、equals()hashCode()toString() 的样板代码,只需声明字段,Java编译器便会自动处理其余部分。本文将通过基础与高级用例示例,以及不适用记录类的场景,带您全面了解Java记录类。

注意:Java记录类在JDK 16中正式定型。

Java编译器如何处理记录类

传统Java创建简单数据类需要大量样板代码。以下通过Java吉祥物Duke和Juggy的示例说明:

public class JavaMascot {private final String name;private final int yearCreated;public JavaMascot(String name, int yearCreated) {this.name = name;this.yearCreated = yearCreated;}public String getName() { return name; }public int getYearCreated() { return yearCreated; }// 为简洁起见,省略equals、hashCode和toString方法
}

使用记录类后,上述代码可简化为单行:

public record JavaMascot(String name, int yearCreated) {}

这一简洁声明自动提供了私有final字段、构造方法、访问器方法,以及正确实现的 equals()hashCode()toString() 方法。

定义记录类后,即可投入使用:

public class RecordExample {public static void main(String[] args) {JavaMascot duke = new JavaMascot("Duke", 1996);JavaMascot juggy1 = new JavaMascot("Juggy", 2005);JavaMascot juggy2 = new JavaMascot("Juggy", 2005);System.out.println(duke); // 输出:JavaMascot[name=Duke, yearCreated=1996]System.out.println(juggy1.equals(juggy2)); // 输出:trueSystem.out.println(duke.equals(juggy1));   // 输出:falseSystem.out.println("吉祥物名称:" + duke.name());System.out.println("创建年份:" + duke.yearCreated());}
}

记录类自动提供有意义的字符串表示、基于值的等值比较,以及与组件名称匹配的简单访问器方法。

自定义记录类

虽然记录类设计简洁,但仍可通过自定义行为增强功能。以下是相关示例。

紧凑型构造方法

记录类提供特殊的“紧凑型构造方法”语法,无需重复参数列表即可验证或转换输入参数:

record JavaMascot(String name, int yearCreated) {// 带验证的紧凑型构造方法public JavaMascot {if (name == null || name.isBlank()) {throw new IllegalArgumentException("名称不能为空");}if (yearCreated < 1995) {throw new IllegalArgumentException("Java吉祥物在1995年前不存在");}}
}

紧凑型构造方法在字段初始化后、对象完全构建前运行,非常适合用于参数验证。此示例中省略了参数声明,但这些参数在构造方法内仍隐式可用。

添加方法

我们还可以为记录类添加方法:

record JavaMascot(String name, int yearCreated) {public boolean isOriginalMascot() {return name.equals("Duke");}public int yearsActive() {return java.time.Year.now().getValue() - yearCreated;}
}

通过添加方法,记录类可在保持语法简洁和不可变性的同时,封装与其数据相关的行为。

接下来,我们探讨记录类更高级的用法。

使用 instanceofswitch 进行模式匹配

Java 21中,记录类成为模式匹配的关键部分,支持switch表达式、组件解构、嵌套模式和守卫条件。

结合增强的 instanceof 运算符,记录类可在类型验证时简洁地提取组件:

record Person(String name, int age) {}if (obj instanceof Person person) {System.out.println("姓名:" + person.name());
}

再看一个经典示例。几何形状是展示密封接口如何与记录类协同工作的典型例子,这种组合使模式匹配尤为清晰。Switch表达式(Java 17引入)的优雅性在此凸显,它让代码简洁且类型安全,类似于函数式语言中的代数数据类型:

sealed interface Shape permits Rectangle, Circle, Triangle {}record Rectangle(double width, double height) implements Shape {}
record Circle(double radius) implements Shape {}
record Triangle(double base, double height) implements Shape {}public class RecordPatternMatchingExample {public static void main(String[] args) {Shape shape = new Circle(5);// 表达性强且类型安全的模式匹配double area = switch (shape) {case Rectangle r -> r.width() * r.height();case Circle c    -> Math.PI * c.radius() * c.radius();case Triangle t  -> t.base() * t.height() / 2;};System.out.println("面积 = " + area);}
}

此例中,Shape 是密封接口,仅允许 RectangleCircleTriangle 实现。由于类型集合封闭,switch表达式覆盖所有情况,无需 default 分支。

Java中的模式匹配

若想进一步探索记录类与模式匹配,请参阅我的近期教程:《Java基础与高级模式匹配》

将记录类用作数据传输对象

记录类在现代API设计(如REST、GraphQL、gRPC或服务间通信)中作为数据传输对象(DTO)表现卓越。其简洁语法和内置等值比较特性,使其成为服务层间映射的理想选择。例如:

record UserDTO(String username, String email, Set<String> roles) {}
record OrderDTO(UUID id, UserDTO user, List<ProductDTO> items, BigDecimal total) {}

DTO在微服务应用中无处不在。使用记录类可使DTO更健壮(得益于不可变性),更简洁(无需编写构造方法、getter及 equals()hashCode() 等方法)

函数式与并发编程中的记录类

作为不可变数据容器,记录类完美契合函数式与并发编程需求。它们既可作为纯函数的返回类型,也可用于流处理管道,还能安全地在线程间共享数据。

由于字段为final且不可变,记录类避免了一整类线程问题。一旦构建完成,其状态无法更改,因此无需防御性复制或同步即可实现线程安全。参考以下示例:

transactions.parallelStream().mapToDouble(Transaction::amount).sum();

由于记录类不可变,此并行计算天生具备线程安全性。

不适用Java记录类的场景

至此,我们已了解记录类的优势,但它们并非万能替代品。例如,所有记录类隐式继承 java.lang.Record,因此无法继承其他类(但可实现接口)。在需要类继承的场景中,记录类并不适用。

以下是记录类不适用的其他情况。

记录类设计为不可变

记录类组件始终为final,因此不适用于需要可变/有状态对象的场景。以下示例展示了一个依赖状态变化的可变类,而记录类不允许此类操作:

public class GameCharacter {private int health;private Position position;public void takeDamage(int amount) {this.health = Math.max(0, this.health - amount);}public void move(int x, int y) {this.position = new Position(this.position.x() + x, this.position.y() + y);}
}

记录类不适合复杂行为建模

基于可变状态、复杂业务逻辑或策略模式、访问者模式、观察者模式等设计,更适合使用传统类实现。以下是复杂逻辑不适用于记录类的示例:

public class TaxCalculator {private final TaxRateProvider rateProvider;private final DeductionRegistry deductions;public TaxAssessment calculateTax(Income income, Residence residence) {// 复杂逻辑不适用于记录类}
}

记录类与某些框架不兼容

部分框架(尤其是ORM)可能无法良好支持记录类。序列化或重度依赖反射的工具也可能存在问题。请务必检查Java特性与技术栈的兼容性:

// 可能无法与某些ORM框架良好协作
record Employee(Long id, String name, Department department) {}// 此时仍需使用传统实体类
@Entity
public class Employee {@Id@GeneratedValueprivate Long id;private String name;@ManyToOneprivate Department department;// Getter、setter、equals、hashCode等方法
}

这些注意事项并不意味着记录类功能不完整,而是强调记录类专为特定场景设计。在某些情况下,传统类仍是更实用的选择。

Java中的记录类与序列化

记录类已在Java生态中被广泛采用,其不可变性使其在持久化、配置和数据传输中极具吸引力。记录类可像普通类一样实现 Serializable 接口。可序列化的记录类组件天然适用于保存配置、恢复状态、网络传输数据或缓存值等场景。

由于记录类字段为final且不可变,它们有助于避免可变状态在序列化与反序列化之间发生变化引发的问题。例如:

import java.io.Serializable;record User(String username, int age, Profile profile) implements Serializable {}class Profile {private String bio;
}

此例中,Stringint 可序列化,但 Profile 不可序列化,因此 User 无法序列化。若将 Profile 也改为实现 Serializable,则 User 将完全可序列化:

class Profile implements Serializable {private String bio;
}

除序列化基础外,Java生态对记录类的支持已迅速成熟。Spring Boot、Quarkus和Jackson等流行框架均与记录类无缝协作,大多数测试工具也是如此。

得益于这种广泛采纳,记录类在实际API中作为DTO表现卓越:

@RestController
@RequestMapping("/api/orders")
public class OrderController {@GetMapping("/{id}")public OrderView getOrder(@PathVariable UUID id) {// 实际应用中,此数据应来自数据库或服务return new OrderView(id,"Duke",List.of(new ItemView(UUID.randomUUID(), 2)),new BigDecimal("149.99"));}// 用于API响应的记录类DTOrecord OrderView(UUID id, String customerName, List<ItemView> items, BigDecimal total) {}record ItemView(UUID productId, int quantity) {}
}

如今,大多数主流Java库和工具已将记录类视为一等公民。早期的质疑已基本消散,开发者正因其清晰性与安全性而广泛接纳记录类。

结语

记录类是Java演进过程中的重大进步。它们降低了数据类的冗余度,并确保了不可变性和行为一致性。通过消除构造方法、访问器及 equals()hashCode() 等方法的样板代码,记录类使代码更简洁、表达力更强,在保持类型安全的同时契合现代实践。

记录类并非适用于所有场景,但在处理不可变数据时优势显著。结合模式匹配,它们能让代码意图更清晰,同时由Java编译器处理样板代码。

随着记录类、密封类和模式匹配等技术的进步,Java正稳步迈向更以数据为中心的编程风格。掌握这些工具是编写现代、高表达力Java代码的最清晰路径之一。


【注】本文译自:Introduction to Java records: Simplified data-centric programming in Java

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

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

相关文章

写个chrome插件屏蔽某些视频,防止孩子看些不正常的视频

写个chrome插件屏蔽某些视频,防止孩子看些不正常的视频Posted on 2025-12-01 11:22 隐客 阅读(0) 评论(0) 收藏 举报manifest.json{"manifest_version": 3,"name": "抖音关键词屏蔽&qu…

ODB和其他C++ ORM框架相比有什么优势?

ODB 作为 C++ 领域的老牌 ORM 框架,与其他 C++ ORM(如 SQLiteCpp、ORMpp、Drogon ORM、Qt SQL 等)相比,在性能、设计理念、功能完整性等方面具有显著优势,以下是其核心竞争力的详细分析: 一、编译期代码生成,极…

2025年cpvc化工管源头厂家权威推荐榜单:upvc化工管/pph化工管/pph工业管源头厂家精选

在现代化工、电子半导体、环保水处理等行业快速发展的背景下,CPVC化工管以其卓越的耐腐蚀性、耐热性及稳定的化学性能,成为腐蚀性介质输送系统的关键材料。数据显示,高性能CPVC管道在强腐蚀环境下的使用寿命可比普通…

论文阅读:《AI大模型时代:向量数据库如何挑战存储极限?》

收获总结:AI不是只靠GPU堆出来的,背后需要一个“聪明”的存储系统——它要能分层、能提速、能省钱,还要适配AI工作流的不同阶段。 核心观点一:AI数据管道是“动态闭环”,不是“一条直线” 很多人以为AI流程就是:…

C++ ODB ORM 从入门到实战应用

C++ ODB ORM 从入门到实战应用 ODB(Object-Relational Mapping)是 C++ 领域成熟的 ORM 框架,由 Code Synthesis 开发,能将 C++ 对象与关系型数据库(如 MySQL、PostgreSQL、SQLite)无缝映射,避免手动编写 SQL 语…

【EF Core】两种方法记录生成的 SQL 语句

原本计划 N 天前写的内容,无奈拖到今天。大伙伴们可能都了解,年近岁末,风干物燥,bug 特多,改需求的精力特旺盛。有几个工厂的项目需要不同程度的修改或修复。这些项目都是老周个人名义与他们长期合作的(有些项目…

ubuntu_12.04_tftp的安装与设置

ubuntu_12.04_tftp的安装与设置 1.安装 tftp-hpa(这是客户端) tftpd-hpa(这是服务端) xinetd(什么是xinetd) sudo apt-get install tftp-hpa tftpd-hpa xinetd2.建立服务的目录tftpboot cd ~mkdir tftpbootchmod -R…

2025年仓储货架厂家综合实力排行榜:三阳货架领跑行业

文章摘要 本文基于中国仓储与配送协会2022-2024年度行业调研数据,对全国主流货架厂家进行综合评估。通过对产品品质、服务能力、技术实力、企业规模四大维度的量化分析,甘肃三阳仓储设备有限公司以94.6分的综合评分位…

2025年知名的企业网站建设价格与服务对照表

2025年知名的企业网站建设价格与服务对照表 行业背景与市场趋势 随着数字化转型的加速推进,企业网站建设已成为品牌展示、客户引流和业务拓展的重要工具。2025年,企业网站建设市场呈现出更加精细化、智能化和个性化…

组装成树

我来为你提供几种Java实现菜单树形结构的方案: 方案一:使用递归构建树形结构 // 菜单实体类 @Data public class Menu { private String code; private String parentCode; private String name; private Integer so…

AI生成代码系列:在不干扰开发者体验的情况下集成开源代码片段检测

AI生成代码系列:在不干扰开发者体验的情况下集成开源代码片段检测转载自FossID AI生成代码:如何快速推进且不破坏现有系统 在生成式人工智能Gen-AI时代,企业应对软件风险管理的方式正发生实质性转变。软件工程团队正…

2025 武汉文化课集训学校权威推荐榜单

随着高考竞争的日益激烈,优质的文化课集训学校成为高三学子提升成绩的重要助力。本榜单基于武汉市教育主管部门资质审核结果、第三方教育评估机构数据及学员真实反馈,从办学资质、师资力量、教学成果、管理体系等维度…

2025年国标mpp电力管直销厂家权威推荐榜单:mpp电力管/mpp电缆保护管/mpp电力管穿线管源头厂家精选

在城市化进程持续加速与电网升级改造的背景下,MPP电力管作为电力电缆保护的核心材料,其质量直接关系到电网工程的安全性与使用寿命。严格的国标产品与规模化源头厂家,已成为市政工程、电网建设等领域采购决策的关键…

2025年密封垫片生产厂家联系方式完整汇总:全国重点企业官方联系方式与高效采购指引

本文基于2025年行业公开数据和中国摩擦密封材料协会报告,结合推荐对象参考内容,从专业能力、服务稳定性、资源网络等维度筛选5个推荐对象,旨在为密封垫片生产厂家领域提供可靠联系方案。根据中国密封材料行业年度报…

标题:2025年密封垫片生产厂家联系方式完整汇总:全国重点企业官方联系方式与高效采购指引

本文基于2025年行业公开数据和权威第三方报告,结合推荐对象参考内容,从专业能力、服务稳定性、资源网络等维度筛选5个推荐对象,旨在为密封垫片生产厂家领域提供可靠联系方案。根据中国摩擦密封材料协会数据显示,20…

2025年评价高的多功能移动餐车十大热门品牌推荐榜

2025年评价高的多功能移动餐车热门品牌推荐榜 开篇:行业背景与市场趋势 随着城市化进程加快和消费升级,移动餐车行业在2025年迎来爆发式增长。这种灵活、低成本的餐饮经营模式不仅满足了消费者对便捷、多样化美食的…

波束赋形MATLAB代码实现

一、波束赋形基本原理 波束赋形(Beamforming)是一种通过控制天线阵列中各阵元的幅度和相位,在特定方向上增强信号强度、抑制干扰的空间滤波技术。核心原理是利用相控阵原理,通过调整各阵元信号的加权系数,使阵列在目…

2025年真空袋厂家联系电话完整汇总:全国重点产区企业联系方式及高效采购指引

本文基于2025年行业公开数据和权威第三方报告,结合推荐对象参考内容,从专业能力、服务稳定性、资源网络等维度筛选5个推荐对象,旨在为真空袋厂家联系电话领域提供可靠联系方案。根据中国包装联合会2024年行业报告显…

2025年三层别墅电梯优质厂家权威推荐榜单:曳引别墅电梯‌/液压别墅电梯‌/液压别墅电梯‌源头厂家精选

在高端住宅需求持续升级的2025年,一台量身定制的三层别墅电梯已成为品质生活的重要标配。据行业数据显示,2024年中国别墅电梯市场规模已达85亿元,同比增长18.3%,预计2025年将突破100亿元大关。 在消费升级与人口老…

2025年知名的南通家纺/设计感家纺高品质好评榜单

2025年知名的南通家纺/设计感家纺高品质好评榜单开篇:中国家纺行业现状与南通市场地位中国家纺行业近年来保持稳健增长态势,2023年市场规模已突破3000亿元,预计到2025年将实现年均6%以上的复合增长率。作为全球的家…