Java Record的使用場(chǎng)景分析
一、前言
- 學(xué)習(xí)新特性Record的作用
二、學(xué)習(xí)內(nèi)容:
- Record與Class的區(qū)別以及Record使用場(chǎng)景
三、問(wèn)題描述
- 為什么引入Record以及Record的作用
四、解決方案:
4.1 為什么引入Record
Java 引入 record 的主要原因是為了簡(jiǎn)化創(chuàng)建不可變數(shù)據(jù)類的過(guò)程,并提高代碼的可讀性和維護(hù)性。
以下是一些具體的原因:
減少樣板代碼:
- ?? record 自動(dòng)生成構(gòu)造器、equals()、hashCode() 和 toString() 方法,以及每個(gè)字段的 getter方法,這樣開(kāi)發(fā)人員就可以專注于業(yè)務(wù)邏輯而不是樣板代碼。
不可變性:
- ?? record 的所有字段默認(rèn)是 final 的,這意味著它們是不可變的。這有助于創(chuàng)建線程安全和易于管理的數(shù)據(jù)模型。
簡(jiǎn)潔性:
- record 允許你用更少的代碼來(lái)定義數(shù)據(jù)類,使得類的定義更加清晰和簡(jiǎn)潔。
性能優(yōu)化:
- record 類型可能?? 受到編譯器的特定優(yōu)化,例如更有效的內(nèi)存布局,從而可能帶來(lái)性能上的提升。
模式匹配的支持:
- record 在模式匹配方面有更好的支持,這在 Java 14 及以后的版本中變得更加重要,尤其是在使用結(jié)構(gòu)化綁定和改進(jìn)的 switch
表達(dá)式時(shí)。
易于調(diào)試:
- 由于 record 自動(dòng)提供了 toString() 方法,因此在調(diào)試時(shí)可以更容易地查看對(duì)象的狀態(tài)。
明確的意圖:
- 使用 record 明確地表明了類的目的是作為一個(gè)簡(jiǎn)單的數(shù)據(jù)載體,這對(duì)于其他開(kāi)發(fā)人員閱讀代碼時(shí)是有幫助的。
4.2 Record與Class區(qū)別
- 觀察下面Class代碼與Record代碼的區(qū)別
- Class
package org.example.recodes;
import java.util.Objects;
public class Cat {
String name;
public String getName() {
return name;
}
public Cat(String name) {
this.name = name;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Cat cat = (Cat) o;
return Objects.equals(name, cat.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}- Record
package org.example.recodes;
public record RecordCat(String name) { }?? 上面兩段代碼是等效的
record 自動(dòng)生成構(gòu)造器、equals()、hashCode() 和 toString() 方法,以及每個(gè)字段的 getter方法
我們運(yùn)行一下下面代碼看看區(qū)別
package org.example.recodes;
public class Main {
public static void main(String[] args) {
Cat cat = new Cat("mimi");
System.out.println(cat.getName());
System.out.println(cat);
RecordCat recordCat = new RecordCat("momo");
System.out.println(recordCat.name());
System.out.println(recordCat);
}
}結(jié)果如下:

4.3 語(yǔ)法與使用場(chǎng)景
適用于那些僅用于存儲(chǔ)數(shù)據(jù)而沒(méi)有復(fù)雜業(yè)務(wù)邏輯的情況
結(jié)構(gòu)體里面可擴(kuò)展內(nèi)容如下
??Record所有字段默認(rèn)是final
- 非靜態(tài)字段:
非靜態(tài)字段要通過(guò)構(gòu)造器(隱式final)去創(chuàng)建,不能在結(jié)構(gòu)體里面自定義- 你不能直接在 record 結(jié)構(gòu)體中手動(dòng)添加非 final 的字段。
- 如果你需要在結(jié)構(gòu)體自定義的字段,推薦使用 class。
// 構(gòu)造傳入
public record Person(String name, int age) {
// 這是合法的,因?yàn)樽侄卧诼暶髦卸x
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導(dǎo)致編譯錯(cuò)誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
} - 實(shí)例方法:
- 除了 record 自動(dòng)生成的方法外,你可以添加自己的實(shí)例方法來(lái)擴(kuò)展 record 的功能。這些方法可以實(shí)現(xiàn)特定的業(yè)務(wù)邏輯或操作。
- 靜態(tài)成員:
- 你可以在 record 中添加靜態(tài)方法,這些方法通常用于工廠模式,即創(chuàng)建 record 實(shí)例的替代構(gòu)造方式。
- 可以添加靜態(tài)字段
- 可以添加靜態(tài)內(nèi)部類
public record Person(String name, int age) {
// 靜態(tài)字段
private static final String DEFAULT_COUNTRY = "Unknown";
// 靜態(tài)方法
public static Person createDefaultPerson() {
return new Person("Anonymous", 0);
}
// 靜態(tài)內(nèi)部類
public static class PersonBuilder {
private String name;
private int age;
public PersonBuilder withName(String name) {
this.name = name;
return this;
}
public Person build() {
return new Person(name, age);
}
}
// 實(shí)例方法
public String introduce() {
return name + " is " + age + " years old";
}
}
// 使用示例
public class Main {
public void example() {
// 使用靜態(tài)方法
Person defaultPerson = Person.createDefaultPerson();
// 使用靜態(tài)內(nèi)部類
Person customPerson = new Person.PersonBuilder()
.withName("John")
.build();
}
} - 私有方法:
- 私有方法可以用來(lái)封裝 record 內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),例如輔助計(jì)算或驗(yàn)證邏輯。
- 嵌套類和內(nèi)部類:
- record 可以包含嵌套類和內(nèi)部類,這些類可以用來(lái)定義相關(guān)的類型,比如枚舉類型或其他輔助類。
- 接口實(shí)現(xiàn):
- record 可以實(shí)現(xiàn)一個(gè)或多個(gè)接口,這樣就可以提供接口中定義的方法的實(shí)現(xiàn)。
- 注解:
- record 可以使用注解來(lái)標(biāo)記,這對(duì)于框架集成、元數(shù)據(jù)處理等非常有用。
- 泛型:
- record 支持泛型,允許你定義泛型參數(shù),從而創(chuàng)建通用的 record 類型。
- 覆蓋默認(rèn)方法:
- 盡管 record 自動(dòng)生成了一些方法,如 equals()、hashCode() 和toString(),你仍然可以覆蓋這些方法以提供不同的實(shí)現(xiàn)。
五、總結(jié):
5.1 場(chǎng)景使用
簡(jiǎn)單的數(shù)據(jù)使用
?? 默認(rèn)只有Getter方法
record Point(int x, int y) {
// 無(wú)需顯式定義構(gòu)造器、equals()、hashCode() 或 toString()
}public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}5.2 字段的定義
?? 在 Java 記錄中,所有字段都必須在記錄的參數(shù)列表中定義。
?? 記錄是不可變的:字段一旦賦值,不能被修改。
?? 無(wú)法在記錄內(nèi)部定義額外的 private final 字段。
下面是相關(guān)解釋
隱式 final:
- 所有記錄字段默認(rèn)是 final,
這意味著它們一旦被初始化,就不能再被修改。
只能通過(guò)構(gòu)造器定義:
- 記錄中的字段必須在
記錄聲明的緊隨其后的參數(shù)列表中定義,不能在記錄的體內(nèi)再次定義或聲明。 - 這意味著
無(wú)法手動(dòng)添加如 private final 字段,直接在類體內(nèi)定義是非法的。
自動(dòng)構(gòu)造器和訪問(wèn)器:
- Java 會(huì)為記錄自動(dòng)生成構(gòu)造器,以及每個(gè)字段的訪問(wèn)器方法(getter)。因此,您不需要手動(dòng)編寫(xiě) getter 方法。
public record Person(String name, int age) {
// 這是合法的,因?yàn)樽侄卧诼暶髦卸x
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導(dǎo)致編譯錯(cuò)誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
}
// 使用記錄的主函數(shù)
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println(person.introduce()); // 輸出:My name is Alice and I am 30 years old.
}
}(后續(xù)有遇到問(wèn)題再添加)
到此這篇關(guān)于Java Record的使用 的文章就介紹到這了,更多相關(guān)java record使用 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MyBatis的@SelectProvider注解構(gòu)建動(dòng)態(tài)SQL方式
這篇文章主要介紹了MyBatis的@SelectProvider注解構(gòu)建動(dòng)態(tài)SQL方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
詳解Spring Data Jpa當(dāng)屬性為Null也更新的完美解決方案
這篇文章主要介紹了詳解Spring Data Jpa當(dāng)屬性為Null也更新的完美解決方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
java 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09
Springboot獲取文件內(nèi)容如何將MultipartFile轉(zhuǎn)File
本文給大家介紹Springboot獲取文件內(nèi)容,將MultipartFile轉(zhuǎn)File方法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-01-01
Spring Security 前后端分離場(chǎng)景下的會(huì)話并發(fā)管理
本文介紹了在前后端分離架構(gòu)下實(shí)現(xiàn)Spring Security會(huì)話并發(fā)管理的問(wèn)題,傳統(tǒng)Web開(kāi)發(fā)中只需簡(jiǎn)單配置sessionManagement()即可實(shí)現(xiàn)會(huì)話數(shù)限制,但在前后端分離場(chǎng)景下,由于采用自定義認(rèn)證過(guò)濾器替代了默認(rèn)的UsernamePasswordAuthenticationFilter,感興趣的可以了解一下2025-08-08
Mybatis-Plus updateById方法更新無(wú)效及空值處理過(guò)程
MyBatis-Plus的updateById默認(rèn)不更新null值以防止誤操作,可通過(guò)UpdateWrapper/LambdaUpdateWrapper顯式設(shè)置,或全局配置、注解@TableField允許字段更新為空,需根據(jù)業(yè)務(wù)場(chǎng)景選擇合適方式2025-07-07
SpringBoot+Vue.js實(shí)現(xiàn)前后端分離的文件上傳功能
這篇文章主要介紹了SpringBoot+Vue.js實(shí)現(xiàn)前后端分離的文件上傳功能,需要的朋友可以參考下2018-06-06

