Java中的record使用詳解
1. 什么是 record?
定義:record 是 Java 14 引入的一種新語(yǔ)法(在 Java 16 中成為正式功能),用于定義不可變的數(shù)據(jù)類。
- 目的:簡(jiǎn)化那些主要用于存儲(chǔ)數(shù)據(jù)的類的定義,減少樣板代碼。
- 特點(diǎn):
- 自動(dòng)實(shí)現(xiàn)構(gòu)造函數(shù)。
- 自動(dòng)生成
equals()、hashCode()和toString()方法。 - 字段默認(rèn)是
private final,且不可修改。
2. 基本語(yǔ)法
public record ClassName(Type fieldName1, Type fieldName2, ...) {
// 可選:可以添加額外的方法或邏輯
}示例
public record Point(int x, int y) {
}等價(jià)于以下傳統(tǒng)類定義:
public final class Point {
private final int x;
private final int y;
// 全參構(gòu)造器
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// Getter 方法
public int x() { return x; }
public int y() { return y; }
// 自動(dòng)覆蓋 equals 和 hashCode
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Point)) return false;
Point other = (Point) obj;
return this.x == other.x && this.y == other.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
// 自動(dòng)覆蓋 toString
@Override
public String toString() {
return "Point[x=" + x + ", y=" + y + "]";
}
}3. record 的核心特性
(1)字段不可變
record的字段默認(rèn)是private final,且不能被修改。- 示例:
public record Point(int x, int y) {}
Point p = new Point(1, 2);
// p.x = 3; // 編譯錯(cuò)誤:x 是 final 的,不能修改(2)自動(dòng)生成方法
- 構(gòu)造函數(shù):根據(jù)字段自動(dòng)生成全參構(gòu)造函數(shù)。
- getter 方法:為每個(gè)字段生成對(duì)應(yīng)的 getter 方法(名稱與字段名相同)。
equals()、hashCode()和toString():根據(jù)字段自動(dòng)生成這些方法。
示例
Point p1 = new Point(1, 2); Point p2 = new Point(1, 2); System.out.println(p1.equals(p2)); // 輸出 true System.out.println(p1.hashCode()); // 輸出基于字段值的哈希碼 System.out.println(p1); // 輸出 Point[x=1, y=2]
(3)簡(jiǎn)潔性
- 不需要手動(dòng)編寫構(gòu)造函數(shù)、getter 方法、
equals()、hashCode()和toString()。 - 適合用來(lái)定義簡(jiǎn)單的數(shù)據(jù)載體類。
4. 使用場(chǎng)景
(1)封裝簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)
- 當(dāng)你需要一個(gè)類來(lái)表示一組不可變的數(shù)據(jù)時(shí),可以使用
record。 - 示例:
public record User(String name, int age) {}
User user = new User("Alice", 25);
System.out.println(user.name()); // 輸出 Alice(2)配置類
- 在 Spring Boot 等框架中,可以用
record定義配置類。 - 示例:
@ConfigurationProperties(prefix = "app")
public record AppProperties(String name, int port) {}(3)DTO(數(shù)據(jù)傳輸對(duì)象)
- 在微服務(wù)或前后端交互中,
record是一個(gè)很好的選擇,用于定義 DTO。 - 示例:
public record BookDto(String title, String author, double price) {}5. 自定義行為
雖然 record 自動(dòng)生成了許多方法,但你仍然可以對(duì)其進(jìn)行擴(kuò)展。
(1)添加額外方法
可以在 record 中定義額外的方法。
public record Point(int x, int y) {
public double distanceFromOrigin() {
return Math.sqrt(x * x + y * y);
}
}
Point p = new Point(3, 4);
System.out.println(p.distanceFromOrigin()); // 輸出 5.0(2)自定義構(gòu)造函數(shù)
你可以通過(guò)緊湊構(gòu)造函數(shù)對(duì)字段進(jìn)行驗(yàn)證或其他操作。
public record Point(int x, int y) {
public Point {
if (x < 0 || y < 0) {
throw new IllegalArgumentException("Coordinates cannot be negative");
}
}
}
// Point p = new Point(-1, 2); // 拋出異常緊湊構(gòu)造函數(shù) 是 record 提供的一種簡(jiǎn)潔語(yǔ)法,用于在不手動(dòng)寫構(gòu)造參數(shù)和賦值的前提下,插入自定義邏輯(如校驗(yàn)),簡(jiǎn)潔高效,專為不可變數(shù)據(jù)對(duì)象設(shè)計(jì)。
6. 注意事項(xiàng)
(1)字段不可變
record的字段默認(rèn)是final,不能被修改。- 如果需要可變字段,不能使用
record。
(2)繼承限制
record不能繼承其他類(因?yàn)樗请[式final的)。- 它的本質(zhì)是一種語(yǔ)法糖,編譯器幫你自動(dòng)生成如下內(nèi)容:
public final class Point extends java.lang.Record {
private final int x;
private final int y;
// 自動(dòng)生成構(gòu)造方法、getters、toString、equals、hashCode 等
}record 可以實(shí)現(xiàn)接口。
public record Point(int x, int y) implements Serializable {}(3)不適合復(fù)雜邏輯
record 主要用于簡(jiǎn)單的數(shù)據(jù)載體,不適合包含復(fù)雜的業(yè)務(wù)邏輯。
(4)兼容性
record需要 JDK 14 或更高版本。- 如果你的項(xiàng)目需要兼容低版本 JDK,則不能使用
record。
7. 總結(jié)
優(yōu)點(diǎn):
- 減少樣板代碼。
- 提高代碼可讀性和維護(hù)性。自動(dòng)生成常用方法(如
equals()、hashCode()和toString())。
適用場(chǎng)景:
- 封裝簡(jiǎn)單數(shù)據(jù)結(jié)構(gòu)。
- 配置類。
- DTO(數(shù)據(jù)傳輸對(duì)象)。
限制:
- 字段不可變。
- 不能繼承其他類。
- 不適合復(fù)雜邏輯。
到此這篇關(guān)于Java中的record詳解的文章就介紹到這了,更多相關(guān)Java record內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中的@Scheduled定時(shí)任務(wù)注解詳解
這篇文章主要介紹了Spring中的@Scheduled定時(shí)任務(wù)注解詳解,要使用@Scheduled注解,首先需要在啟動(dòng)類添加@EnableScheduling,啟用Spring的計(jì)劃任務(wù)執(zhí)行功能,這樣可以在容器中的任何Spring管理的bean上檢測(cè)@Scheduled注解,執(zhí)行計(jì)劃任務(wù),需要的朋友可以參考下2023-09-09
mybatis的動(dòng)態(tài)SQL以及連接池詳解
這篇文章主要介紹了mybatis的動(dòng)態(tài)SQL以及連接池詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
mybatis插入數(shù)據(jù)不返回主鍵id的可能原因及解決方式
這篇文章主要介紹了mybatis插入數(shù)據(jù)不返回主鍵id的可能原因及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問(wèn)題分析及解決方案)
這篇文章主要介紹了IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包 的解決方案,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
kafka?消息隊(duì)列中點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱的區(qū)別說(shuō)明
這篇文章主要介紹了kafka?消息隊(duì)列中點(diǎn)對(duì)點(diǎn)與發(fā)布訂閱的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Java中父類強(qiáng)制轉(zhuǎn)換子類問(wèn)題解決
在Java編程中繼承是基礎(chǔ),但父類轉(zhuǎn)換為子類時(shí)需謹(jǐn)慎,正確的轉(zhuǎn)換要求父類引用實(shí)際指向子類對(duì)象,錯(cuò)誤轉(zhuǎn)換可能引發(fā)ClassCastException,解決方案包括使用instanceof關(guān)鍵字檢查、利用泛型避免轉(zhuǎn)換、以及通過(guò)多態(tài)性避免直接轉(zhuǎn)換,感興趣的可以了解一下2024-11-11
Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例
這篇文章主要介紹了Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
Springboot Apollo配置yml的問(wèn)題及解決方案
這篇文章主要介紹了Springboot Apollo配置yml的問(wèn)題及解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06

