最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 記錄類Record詳解

 更新時間:2025年09月22日 09:54:14   作者:探索java  
文章介紹了Java記錄類的引入背景、語法特點及優(yōu)勢,包括自動生成構(gòu)造器、訪問器、equals、hashCode、toString等方法,強調(diào)其不可變性與類型安全性,適合用于數(shù)據(jù)封裝,并通過示例和注意事項說明其使用場景與局限,感興趣的朋友跟隨小編一起看看吧

引言

在傳統(tǒng) Java 開發(fā)中,創(chuàng)建一個純粹用于封裝數(shù)據(jù)的類(如 DTO 或值對象)往往需要編寫大量樣板代碼,包括構(gòu)造器、getter、equals、hashCode 和 toString 方法。這些代碼雖然重復(fù),卻難以避免,不僅影響開發(fā)效率,也降低了代碼可讀性。

為了解決這一問題,Java 在 JEP 359 中提出了“記錄類”這一語言特性,并于 Java 14 首次以預(yù)覽形式引入,在 Java 16 中正式發(fā)布。記錄類的核心設(shè)計目標是為數(shù)據(jù)攜帶類提供一種簡潔、可讀性強且類型安全的聲明方式。

本篇文章將帶你深入理解記錄類的原理與使用,掌握其各種高級特性,并通過豐富示例、性能對比和最佳實踐指導(dǎo),助你在實際項目中合理使用記錄類,寫出更加優(yōu)雅、現(xiàn)代化的 Java 代碼。

語法與基本用法

記錄類的定義方式非常簡單,使用 record 關(guān)鍵字聲明,取代了傳統(tǒng)類的冗長結(jié)構(gòu)?;菊Z法如下:

public record Person(String name, int age) {
}

上述代碼定義了一個 Person 記錄類,包含兩個組件(component):nameage,它們將被編譯器自動提升為私有 final 字段,并生成相應(yīng)的方法(稍后將詳細介紹)。

與傳統(tǒng)類相比,記錄類具備以下特性:

  • 自動生成構(gòu)造器、訪問器、equalshashCode、toString。
  • 所有字段默認 private final
  • 構(gòu)造器參數(shù)與字段一一對應(yīng)。
  • 支持接口實現(xiàn)、泛型和靜態(tài)成員。

示例:基本記錄類定義

public record Book(String title, double price) {
}
public class Main {
    public static void main(String[] args) {
        Book book = new Book("Java 精通之路", 79.9);
        System.out.println(book.title());
        System.out.println(book);
    }
}

輸出結(jié)果:

Java 精通之路
Book[title=Java 精通之路, price=79.9]

自動生成方法詳解

記錄類的核心價值之一是其自動生成的標準方法,這不僅減少了開發(fā)者的重復(fù)工作,也保證了行為的一致性和語義清晰性。以下是記錄類在編譯階段自動生成的方法列表:

  • 所有字段的 訪問器方法(accessor)
  • 一個 規(guī)范構(gòu)造器(canonical constructor)
  • equals(Object obj) 方法
  • hashCode() 方法
  • toString() 方法

1. 訪問器方法

每個組件都會生成一個訪問器方法,其方法名與字段名一致。例如:

public record User(String username, String role) {
}
User user = new User("alice", "admin");
System.out.println(user.username()); // 輸出:alice
System.out.println(user.role());     // 輸出:admin

注意:記錄類不生成傳統(tǒng)的 getUsername() 形式的方法。

2. equals 和 hashCode 方法

記錄類會基于字段值自動生成合理的 equalshashCode 方法。

User user1 = new User("alice", "admin");
User user2 = new User("alice", "admin");
System.out.println(user1.equals(user2)); // true
System.out.println(user1.hashCode() == user2.hashCode()); // true

比較是基于組件值進行的,而非引用。

3. toString 方法

記錄類默認實現(xiàn)了符合邏輯的 toString() 方法,格式為:類名[字段1=值1, 字段2=值2]

System.out.println(user1.toString());
// 輸出:User[username=alice, role=admin]

4. 規(guī)范構(gòu)造器

編譯器會生成一個公共構(gòu)造器,其參數(shù)列表與組件順序一致:

public User(String username, String role) {
    this.username = username;
    this.role = role;
}

此構(gòu)造器不能省略字段賦值,且不能繞過不可變性。

不可變性的特性與價值

記錄類的一個顯著特性是:不可變性(Immutability)。一旦創(chuàng)建了記錄類實例,其狀態(tài)便不可更改,這使得記錄類天然適合用于線程安全的數(shù)據(jù)傳遞、緩存鍵、日志記錄和函數(shù)式編程等場景。

不可變性的實現(xiàn)方式

在記錄類中:

  • 所有組件字段默認是 private final,且不能被修改。
  • 沒有生成 setter 方法。
  • 構(gòu)造函數(shù)中必須為所有字段賦值,且不能通過反射等方式繞過字段 final 的限制(除非使用非法手段)。
public record Customer(String id, String name) {
    // 無法修改 id 和 name
}
Customer c1 = new Customer("001", "Alice");
c1.name = "Bob"; // 編譯錯誤,字段是 final 的

不可變性的優(yōu)勢

  • 線程安全:多個線程可安全共享記錄類實例,而無需加鎖。
  • 更少的副作用:狀態(tài)不可更改,避免由于共享狀態(tài)帶來的錯誤。
  • 更簡單的調(diào)試與測試:數(shù)據(jù)不會在調(diào)用鏈中被意外修改,提高可預(yù)測性。
  • 易于緩存和哈希結(jié)構(gòu)使用:不可變對象可作為 Map 的鍵,不會影響哈希值。

與傳統(tǒng)類的對比

在傳統(tǒng) Java 類中,需要人為地將字段設(shè)置為 private final,并避免提供 setter 方法,才能勉強模擬不可變性:

public final class ImmutablePerson {
    private final String name;
    private final int age;
    public ImmutablePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
}

記錄類通過語法層級的約束,天然支持不可變性,避免了人為失誤。

注意事項:深層不可變性

雖然記錄類本身是不可變的,但如果其字段是可變對象(如 List、Map、數(shù)組),則需要謹慎處理。

public record UserProfile(String username, List<String> tags) {
}
List<String> list = new ArrayList<>();
list.add("java");
UserProfile profile = new UserProfile("bob", list);
profile.tags().add("record"); // 可變字段被修改

上述代碼中,雖然 tags 字段本身是 final,但它引用的是一個可變列表,因此對象并不是真正不可變。

解決方案:

  • 在構(gòu)造函數(shù)中進行 defensive copy(防御性復(fù)制)。
  • 使用 List.copyOf() 創(chuàng)建不可變集合。
public record SafeUserProfile(String username, List<String> tags) {
    public SafeUserProfile {
        tags = List.copyOf(tags);
    }
}

這樣就能保證 tags 無法在外部被修改,真正實現(xiàn)深層不可變。

構(gòu)造器機制

盡管記錄類自動為我們生成了標準構(gòu)造器,但在實際開發(fā)中,仍有很多場景需要我們自定義構(gòu)造邏輯,比如字段校驗、數(shù)據(jù)轉(zhuǎn)換等。Java 記錄類支持三種構(gòu)造器形式:

  • 規(guī)范構(gòu)造器(Canonical Constructor)
  • 緊湊構(gòu)造器(Compact Constructor)
  • 自定義構(gòu)造器(Custom Constructor)

規(guī)范構(gòu)造器(Canonical Constructor)

規(guī)范構(gòu)造器是由編譯器自動生成的構(gòu)造函數(shù),其參數(shù)列表與組件順序一致,默認行為是將所有字段賦值:

public record Product(String name, double price) {
    // 編譯器生成如下構(gòu)造器:
    // public Product(String name, double price) {
    //     this.name = name;
    //     this.price = price;
    // }
}

我們也可以顯式地定義規(guī)范構(gòu)造器,來加入自定義邏輯,例如參數(shù)校驗:

public record Product(String name, double price) {
    public Product {
        if (price < 0) {
            throw new IllegalArgumentException("價格不能為負數(shù)");
        }
    }
}

緊湊構(gòu)造器(Compact Constructor)

Java 為記錄類提供了一種語法糖,稱為“緊湊構(gòu)造器”。在緊湊構(gòu)造器中,我們無需列出參數(shù)列表,編譯器會自動將構(gòu)造器參數(shù)與字段綁定。

public record Student(String name, int age) {
    public Student {
        if (age < 0) {
            throw new IllegalArgumentException("年齡不能為負數(shù)");
        }
    }
}

等價于:

public record Student(String name, int age) {
    public Student(String name, int age) {
        if (age < 0) {
            throw new IllegalArgumentException("年齡不能為負數(shù)");
        }
        this.name = name;
        this.age = age;
    }
}

緊湊構(gòu)造器簡化了字段賦值過程,適用于多數(shù)校驗邏輯場景。

自定義構(gòu)造器與重載

記錄類可以定義額外的構(gòu)造器,但這些構(gòu)造器必須調(diào)用規(guī)范構(gòu)造器,不能繞過字段賦值流程:

public record Coordinate(int x, int y) {
    public Coordinate() {
        this(0, 0); // 默認構(gòu)造
    }
    public Coordinate(int value) {
        this(value, value); // 重載構(gòu)造
    }
}

注意:

  • 所有非規(guī)范構(gòu)造器都必須顯式調(diào)用 this(...)。
  • 不能定義不初始化所有字段的構(gòu)造器。

通過構(gòu)造器機制,記錄類不僅保持了不可變性,還為開發(fā)者提供了足夠的靈活性,用于字段校驗、默認值填充、工廠構(gòu)造等實際需求。

高級特性

記錄類雖然語法簡潔,但功能并不簡單。它支持許多高級語言特性,包括靜態(tài)成員、接口實現(xiàn)、泛型定義以及本地記錄類的聲明,使其具備在復(fù)雜應(yīng)用中廣泛使用的能力。

靜態(tài)成員

記錄類可以像普通類一樣包含靜態(tài)字段、靜態(tài)方法和靜態(tài)代碼塊,這些靜態(tài)成員的行為與傳統(tǒng)類完全一致。

public record Color(int red, int green, int blue) {
    public static final Color BLACK = new Color(0, 0, 0);
    public static final Color WHITE = new Color(255, 255, 255);
    public static String toHex(Color c) {
        return String.format("#%02x%02x%02x", c.red(), c.green(), c.blue());
    }
}
Color white = Color.WHITE;
System.out.println(Color.toHex(white)); // 輸出:#ffffff

接口實現(xiàn)

記錄類可以實現(xiàn)接口(包括函數(shù)式接口),并提供對應(yīng)方法實現(xiàn)。

public interface Identifiable {
    String id();
}
public record Employee(String id, String name) implements Identifiable {
    // 自動實現(xiàn) id() 方法
}

記錄類實現(xiàn)接口時,可以通過組件直接滿足接口方法簽名,進一步提升了類型的表達力。

泛型支持

記錄類可以定義為泛型類型,從而適用于多種數(shù)據(jù)類型的封裝。

public record Pair<K, V>(K key, V value) {
}
Pair<String, Integer> entry = new Pair<>("age", 30);
System.out.println(entry.key());   // 輸出:age
System.out.println(entry.value()); // 輸出:30

泛型記錄類尤其適用于通用值對象、鍵值對封裝、元組等使用場景。

本地記錄類(Local Records)

從 Java 16 開始,記錄類也可以在方法內(nèi)部定義,稱為“本地記錄類”,適用于封裝局部方法邏輯中的中間數(shù)據(jù)結(jié)構(gòu)。

public class ReportGenerator {
    public void generate() {
        record Summary(String title, int count) {}
        Summary summary = new Summary("周報", 12);
        System.out.println(summary);
    }
}

本地記錄類只在方法范圍內(nèi)可見,能夠提升臨時數(shù)據(jù)處理的類型安全性與可讀性,避免引入冗余的外部類定義。

通過這些高級特性,記錄類在保持簡潔的同時,依然具備高度靈活性,能夠應(yīng)對多種開發(fā)需求,適用于從簡單 DTO 到泛型模型、工具類的廣泛場景。

限制與注意事項

盡管記錄類極大簡化了不可變數(shù)據(jù)類的開發(fā),但其設(shè)計也存在一些固有的限制,了解這些限制有助于合理使用,避免不合適的場景導(dǎo)致代碼設(shè)計問題。

1. 繼承限制

  • 記錄類隱式繼承自 java.lang.Record,不允許繼承其他類。
  • 記錄類本身是 final 的,不能被繼承。
  • 這意味著無法通過繼承擴展記錄類行為,只能通過組合或接口實現(xiàn)進行擴展。
// 編譯錯誤,記錄類不能繼承其他類 public record MyRecord extends SomeClass { } // 編譯錯誤,記錄類不能被繼承 public class SubRecord extends MyRecord { }

2. 字段限制

  • 所有組件字段自動為 private final,不能定義非 final 字段。
  • 不支持額外的實例字段,只能通過靜態(tài)字段擴展類功能。

3. 不支持無參構(gòu)造器

  • 記錄類必須初始化所有組件字段,不能定義無參構(gòu)造器。
  • 但可通過自定義構(gòu)造器為字段賦默認值,實現(xiàn)類似無參構(gòu)造器的效果。

4. 不支持可變字段

  • 記錄類設(shè)計為不可變,因此組件字段不能是可變的。
  • 如果字段引用了可變對象,需自行保證深不可變性(如使用不可變集合或防御性復(fù)制)。

5. 限制擴展性

  • 由于不能繼承和添加實例字段,記錄類不適合表示需要復(fù)雜行為和狀態(tài)管理的實體。
  • 更適合用于簡單數(shù)據(jù)載體(如 DTO、值對象)。

6. 序列化限制

  • 記錄類實現(xiàn)了 Serializable,但序列化時遵循組件字段的序列化規(guī)則。
  • 如果字段不可序列化,會導(dǎo)致序列化失敗。

理解并遵守這些限制,有助于避免誤用記錄類導(dǎo)致設(shè)計不佳和維護困難。

到此這篇關(guān)于Java 記錄類Record詳解的文章就介紹到這了,更多相關(guān)Java Record 類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解SpringBoot中的統(tǒng)一異常處理

    詳解SpringBoot中的統(tǒng)一異常處理

    這篇文章主要介紹了詳解SpringBoot中的統(tǒng)一異常處理,在獨立的某個地方,比如單獨一個類,定義一套對各種異常的處理機制,需要的朋友可以參考下
    2023-05-05
  • 使用Java繪制心形動畫的代碼示例

    使用Java繪制心形動畫的代碼示例

    Java動態(tài)愛心代碼是一種簡單而精美的動態(tài)效果,這篇文章主要介紹了使用Java繪制心形動畫的代碼示例,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-06-06
  • 詳解Java線程池如何統(tǒng)計線程空閑時間

    詳解Java線程池如何統(tǒng)計線程空閑時間

    這篇文章主要和大家分享一個面試題:Java線程池是怎么統(tǒng)計線程空閑時間?文中的示例代碼講解詳細,對我們掌握Java有一定幫助,需要的可以參考一下
    2022-11-11
  • mybatis攔截器自動加密解密教程

    mybatis攔截器自動加密解密教程

    這篇文章主要介紹了mybatis攔截器自動加密解密案例,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-08-08
  • Spring Boot 與 Apache Pulsar 集成構(gòu)建高性能消息系統(tǒng)實踐應(yīng)用案例

    Spring Boot 與 Apache Pulsar 集成構(gòu)建高性能

    本文介紹了ApachePulsar作為新一代消息中間件的特點,并詳細說明了如何在SpringBoot應(yīng)用Pulsar,還介紹了Pulsar的高級特性和實踐應(yīng)用案例,如訂單處理系統(tǒng)和實時數(shù)據(jù)分析,感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • Java 邏輯控制全面詳解

    Java 邏輯控制全面詳解

    程序的邏輯主要分為三種結(jié)構(gòu):順序結(jié)構(gòu)、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu),順序結(jié)構(gòu)的所有的代碼都是從前向后執(zhí)行的。有些時候順序是由“{}”為界限的,下文將全面詳細的介紹
    2021-10-10
  • 分布式任務(wù)調(diào)度xxl-job問題解決

    分布式任務(wù)調(diào)度xxl-job問題解決

    這篇文章主要為大家介紹了分布式任務(wù)調(diào)度xxl-job的問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多多多進步,早日升職加薪
    2022-03-03
  • java懶惰評估實現(xiàn)方法

    java懶惰評估實現(xiàn)方法

    這篇文章主要介紹了java懶惰評估如何實現(xiàn)的相關(guān)內(nèi)容及實例,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-05-05
  • 基于Java 數(shù)組內(nèi)存分配的相關(guān)問題

    基于Java 數(shù)組內(nèi)存分配的相關(guān)問題

    本篇文章是對Java中數(shù)組內(nèi)存分配進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Java?Arrays.copyOf?功能示例代碼

    Java?Arrays.copyOf?功能示例代碼

    Arrays.copyOf功能是實現(xiàn)數(shù)組的復(fù)制,返回復(fù)制后的數(shù)組,這篇文章主要介紹了Java?Arrays.copyOf?功能,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03

最新評論

莱阳市| 界首市| 上虞市| 岳普湖县| 莒南县| 泽库县| 达拉特旗| 卓资县| 特克斯县| 石林| 清原| 成都市| 龙南县| 六枝特区| 商丘市| 永定县| 和政县| 楚雄市| 和田市| 宣化县| 天长市| 吐鲁番市| 泰州市| 芦溪县| 沾化县| 连平县| 阜康市| 通渭县| 兴宁市| 台东县| 溧阳市| 南皮县| 彰化县| 门源| 樟树市| 故城县| 江孜县| 新兴县| 汾阳市| 靖边县| 定陶县|