」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Java 中的記錄與類別

Java 中的記錄與類別

發佈於2024-11-02
瀏覽:444

Records vs Clases en Java

如果您已经了解 Java 中的 records,您可能会发现它的用法与类非常相似,但是有一些重要的差异必须考虑。在本文中,我们将了解 Java 中的 recordsclasses 之间的差异。如果您仍然不知道记录,我建议阅读我的帖子《Java 中的记录:它们是什么以及如何使用它们》。

不变性

不可变对象是指一旦创建对象,其属性就无法修改的对象。对于 records,它们是不可变的,也就是说,一旦创建 record 类型的对象,其属性就无法修改。另一方面,类可能是不变的,也可能不是不变的,具体取决于它的实现方式。这部分确保数据的完整性并防止其被意外修改。

目的

类通常只是为了存储数据而编写,例如来自数据库查询的数据或来自表单的数据。在许多情况下,该数据是不可变的,因为需要在不使用同步的情况下确保数据的有效性。为了实现这一点,使用以下元素编写一个类:

  • 每个字段的私有属性。
  • 每个字段的获取器。
  • 初始化所有字段的构造函数。
  • 比较对象是否相等的 equals 方法。
  • hashCode 方法,根据字段生成哈希码。
  • 生成字段的字符串表示形式的 toString 方法。

例如,如果你有一个Person类,有两个属性name和lastName,你可以这样写:

public class Person {

    private final String name;
    private final String lastName;

    public Person(String name, String lastName) {
        this.name = name;
        this.lastName = lastName;
    }

    public String getName() {
        return name;
    }

    public String getLastName() {
        return lastName;
    }

    @Override
    public String toString() {
        return "Person{"   "name='"   name   '\''  
                ", lastName='"   lastName   '\''  
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person person)) return false;
        return Objects.equals(getName(), person.getName()) && Objects.equals(getLastName(), person.getLastName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getLastName());
    }
}

这是该任务的解决方案,但它是实际需要的大量代码。如果类具有更多属性,即使在 IDE 或 GitHub Copilot 等插件的帮助下完成,编写的代码也会更长。更好的解决方案是将我们的类声明为数据类,即仅存储数据的类,并且不必具有特定行为,这就是 records 的用武之地。

这样Person类就可以重写为记录如下:

public record Person(String name, String lastName) { }

这会自动生成 equals、hashCode 和 toString 方法,以及每个属性的 getter 方法。

记录和类之间有什么区别?

  • 不可变性records是不可变的,也就是说,一旦创建了record类型的对象,它的属性就不能被修改。相反,类可能是不变的,也可能不是不变的,具体取决于它的实现方式。
  • 生成的方法records自动生成equals、hashCode和toString方法,以及每个属性的getter方法。然而,在类中,这些方法必须手动实现或借助 IDE 实现。
  • 在OOP中使用记录不能从其他类继承,也不能被其他类扩展,但它们可以实现接口。另一方面,类可以从其他类继承、扩展,并且通常非常适合涵盖面向对象编程的概念。
  • 语法记录的语法比类简单,因为它可以在一行中定义,而类需要多行代码。
  • 目的记录是一种类似于DTO(数据传输对象)的结构,即帮助建模不可变数据的类,其本身是 是一个更通用的结构,可以有行为和状态。

何时使用记录,何时使用类?

如果需要的是一个不可变的数据结构来存储数据,并且不需要对属性进行任何修改(简单地看成是一个携带信息的对象)。另一方面,如果您需要具有独特逻辑和特定方法的更通用的结构、面向对象范例的方法、应用设计模式或使用 JPA 或 Hibernate 等,那么您应该使用类。

额外:具有可变属性的记录

让我们考虑以下示例,有两条记录 Product,其属性为名称和价格,还有 Cart,其具有 ArrayList 类型的单个属性 products 以及一些获取产品数量和购物车总数的方法。

package org.jordi.example;

public record Product(String name, double price) { }
package org.jordi.example;

import java.util.ArrayList;
import java.util.List;

public record Cart(List products) {

    public Cart() {
        this(new ArrayList());
    }

    public int getQuantity() {
        return this.products.size();
    }

    public double getTotal() {
        return this.products.stream().mapToDouble(Product::price).sum();
    }
}

这种情况下的问题是,每个 record 本身都是不可变的,但在记录 Cart 的情况下,它具有 ArrayList 类型的属性,并且由于 ArrayList 本质上是可变的,记录Cart实例化后即可修改列表内容。

package org.jordi.example;

public class Main {
    public static void main(String[] args) {
        Product water = new Product("Water", 15);
        Product milk = new Product("Milk", 22);

        Cart cart = new Cart();
        cart.products().add(water);
        cart.products().add(milk);
        System.out.println("Price: "   cart.getTotal());

        cart.products().clear();
        System.out.println("Quantity: "   cart.getQuantity());
        System.out.println("Price: "   cart.getTotal());
    }
}

上面的代码编译没有问题,因为只修改了列表的内容,但产品属性本身没有被修改。这只是特定情况的示例,可能没有必要,但很高兴知道可以这样做。

版本聲明 本文轉載於:https://dev.to/asjordi/records-vs-clases-en-java-1bb6?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • x86 彙編中的「鎖定」指令是否無限期地保留匯流排?
    x86 彙編中的「鎖定」指令是否無限期地保留匯流排?
    理解x86彙編中的“Lock”指令x86彙編中的“lock”指令是一個前綴,它強制後續指令對總線的獨佔所有權。這可確保 CPU 在該指令的持續時間內完全控制高速緩存行。 停用總線鎖定與通常的理解相反,「lock」前綴不會導致 CPU 鎖定無限期的公車。執行後續指令後,鎖會被釋放。這允許 CPU 僅在...
    程式設計 發佈於2024-11-08
  • Top itemmap Scraper 你該知道的 4
    Top itemmap Scraper 你該知道的 4
    有時需要組織並包含在新網站設計中的資訊量可能會令人難以承受,從而使任務變得更加困難。網站地圖是一個有用的規劃工具,可以幫助組織和簡化網站上需要的材料並刪除任何不需要的頁面。此外,精心設計的網站地圖可為訪客提供正面的體驗,從而提高轉換率。 多年來,最好的網頁設計方法一直包括網站地圖;因此,它們並不是...
    程式設計 發佈於2024-11-08
  • 如何在 Web 瀏覽器中追蹤 XMLHttpRequest 的進度更新?
    如何在 Web 瀏覽器中追蹤 XMLHttpRequest 的進度更新?
    取得 XMLHttpRequest 的進度更新Web 瀏覽器為用戶端伺服器資料交換提供 XMLHttpRequest (XHR) 物件。雖然標準 XHR API 缺乏固有的進度追蹤功能,但有一些方法可以監控資料傳輸的進度。 上傳位元組數:XHR 公開 xhr.upload。 onprogress 事...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中向回呼函數傳遞參數?
    如何在 JavaScript 中向回呼函數傳遞參數?
    在JavaScript 中向回調函數傳遞參數在JavaScript 中,回呼函數通常用於在某個事件發生後執行特定任務。在定義這些函數時,通常需要向它們傳遞相關資料或參數。 傳遞參數的簡單方法是在呼叫回呼函數時將它們明確地設定為實參。例如:function tryMe(param1, param2) ...
    程式設計 發佈於2024-11-08
  • 與 Jira 和 LLM 的互動專案報告
    與 Jira 和 LLM 的互動專案報告
    For all projects I worked on, I used some sort of project management system where project scope was defined as a list of tasks (tickets), and progress...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中對不同格式的日期數組進行排序?
    如何在 PHP 中對不同格式的日期數組進行排序?
    PHP 日期數組排序在 PHP 中對日期數組進行排序可能很棘手,特別是當日期不是標準化格式時。 In根據您的具體情況,您有不同格式的日期數組,例如“11-01-2012”和“01-01-2014”。使用 asort 函數(按升序對數組進行排序)在這種情況下不起作用,因為它將每個日期視為字串並忽略年-...
    程式設計 發佈於2024-11-08
  • 機器學習中的 C++:逃離 Python 與 GIL
    機器學習中的 C++:逃離 Python 與 GIL
    介紹 當 Python 的全域解釋器鎖定 (GIL) 成為需要高並發或原始效能的機器學習應用程式的瓶頸時,C 提供了一個引人注目的替代方案。這篇部落格文章探討如何利用 C 語言進行 ML,並專注於效能、並發性以及與 Python 的整合。 閱讀完整的部落格! ...
    程式設計 發佈於2024-11-08
  • 如何使用 PHP 和 MySQL 以印地語儲存和顯示 Unicode 字串?
    如何使用 PHP 和 MySQL 以印地語儲存和顯示 Unicode 字串?
    使用PHP 和MySQL 儲存和顯示Unicode 字串(हिन्दी)嘗試儲存和顯示Unicode 字串時,您可能會遇到挑戰,特別是在印地語等語言中,由於編碼問題。為了解決這些問題,必須在資料庫和 PHP 腳本中設定適當的字元編碼和排序規則。 資料庫配置對於 MySQL資料庫,將資料庫和資料表編碼...
    程式設計 發佈於2024-11-08
  • 如何在 PHP 中將 UTF-8 字元轉換為 ISO-8859-1 並返回?
    如何在 PHP 中將 UTF-8 字元轉換為 ISO-8859-1 並返回?
    將UTF-8 字元轉換為ISO-88591 並傳回PHP當使用使用不同編碼的多個腳本時,需要在字元集之間進行轉換。其中一種轉換涉及將 UTF-8 字元轉換為 ISO-88591,反之亦然。 儘管存在 utf_encode() 和 _decode(),但將 UTF-8 直接轉換為 ISO-88591 ...
    程式設計 發佈於2024-11-08
  • 以下是一些標題選項,使用問題格式,重點關注文章中提出的挑戰和解決方案:

選項 1(直接且簡潔):
* 如何避免 Angul 中的模板標籤衝突
    以下是一些標題選項,使用問題格式,重點關注文章中提出的挑戰和解決方案: 選項 1(直接且簡潔): * 如何避免 Angul 中的模板標籤衝突
    為AngularJS 和Django 定制模板標籤由於模板標籤衝突,將AngularJS 與Django 集成可能會帶來挑戰,兩者都使用{{}}。為了克服這個問題,需要調整 AngularJS 或 Django 的模板標籤語法。 AngularJS 範本標籤自訂:在 AngularJS 1.0 中,...
    程式設計 發佈於2024-11-08
  • 每個開發人員都應該了解的高階 JavaScript 概念
    每個開發人員都應該了解的高階 JavaScript 概念
    JavaScript 是许多开发人员日常使用的语言,但其生态系统中存在许多隐藏的瑰宝,即使是经验丰富的开发人员也可能不熟悉。本文探讨了一些鲜为人知的 JavaScript 概念,它们可以显着提高您的编程技能。我们将介绍 代理、符号、生成器等概念,通过示例演示每个概念并解决问题以说明其强大功能。 最...
    程式設計 發佈於2024-11-08
  • 直接用mysqli_函數取代mysql_函數會帶來挑戰嗎?
    直接用mysqli_函數取代mysql_函數會帶來挑戰嗎?
    盲目地用 mysqli_ 取代 mysql_ 函數會導致問題嗎? 將程式碼庫更新到 PHP 7 需要將已棄用的 mysql_ 函數替換為 mysqli_ 對應函數。然而,一個常見的誤解是您可以直接進行全面替換。 答案:不,事情沒那麼簡單雖然函數名稱可能會出現類似地,與 mysql_ 相比,mysql...
    程式設計 發佈於2024-11-08
  • 為什麼 `malloc()` 在 C++ 中會導致「無效轉換」錯誤?
    為什麼 `malloc()` 在 C++ 中會導致「無效轉換」錯誤?
    Malloc 分配問題:了解「無效轉換」錯誤提供的程式碼在嘗試使用malloc 分配記憶體時引入了一個常見問題( )。此錯誤源自於將 malloc() 的回傳值直接指派給 char 指標而沒有進行正確的轉換。 malloc() 函數在堆中保留一塊記憶體並傳回一個通用的 void 指標。但是,程式碼將...
    程式設計 發佈於2024-11-08
  • 如何在 Zend Framework 中確定客戶端的時區?
    如何在 Zend Framework 中確定客戶端的時區?
    客戶端時區確定確定客戶端時區對於時間敏感的應用程式至關重要。這個問題探討如何在 Zend Framework 中取得此資訊。 以秒偏移量形式檢索時區取得時區的首選方法是作為 UTC 的秒數。例如,俄羅斯莫斯科將返回 36060,而英國倫敦將返回 0。 建議的解決方案建議的解決方案涉及利用jQuery...
    程式設計 發佈於2024-11-08
  • 如何使用 React 建立通知功能
    如何使用 React 建立通知功能
    Hello everyone ?? In today's tutorial, we'll guide you through building a real-time notifications feature using SuperViz, a powerful platform for rea...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3