「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Java のレコードとクラス

Java のレコードとクラス

2024 年 11 月 2 日に公開
ブラウズ:218

Records vs Clases en Java

Java の records をすでに知っている場合は、その使用法がクラスの使用法と非常に似ていることに気づくかもしれませんが、考慮する必要がある重要な違いがあります。この記事では、Java の recordsclasses の違いを見ていきます。 レコードをまだ知らない場合は、私の投稿「Java のレコード: レコードの内容とその使用方法」を読むことをお勧めします。

不変性

不変オブジェクトとは、オブジェクトの作成後にその属性を変更できないオブジェクトです。 records の場合、これらは不変です。つまり、タイプ record のオブジェクトが作成されると、その属性は変更できません。一方、クラスは実装方法に応じて不変である場合とそうでない場合があります。この部分はデータの整合性を保証し、誤って変更されることを防ぎます。

目的

クラスは通常、データベース クエリからのデータやフォームからのデータなど、単にデータを保存するために作成されます。多くの場合、同期を使用せずにデータの有効性を保証する必要があるため、このデータは不変です。これを実現するには、次の要素を使用してクラスを作成します:

  • 各フィールドのプライベート属性。
  • 各フィールドのゲッター。
  • すべてのフィールドを初期化するコンストラクター。
  • オブジェクトが等しいかどうかを比較するequalsメソッド。
  • フィールドに基づいてハッシュ コードを生成する hashCode メソッド。
  • フィールドの文字列表現を生成する toString メソッド。

たとえば、name と lastName という 2 つの属性を持つ Person クラスがある場合、次のように記述できます。

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 クラスを record として書き換えることができます:

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

これにより、equals、hashCode、toString メソッドと、各属性の getter メソッドが自動的に生成されます。

レコードとクラスの違いは何ですか?

  • 不変性: records は不変です。つまり、タイプ record のオブジェクトが作成されると、その属性は変更できません。代わりに、クラスは実装方法に応じて不変になる場合とそうでない場合があります。
  • 生成されたメソッド: レコードは、各属性のゲッター メソッドに加えて、equals、hashCode、toString メソッドを自動的に生成します。ただし、クラスでは、これらのメソッドは手動で、または IDE の助けを借りて実装する必要があります。
  • OOP での使用: records は他のクラスから継承したり、他のクラスによって拡張したりできませんが、インターフェイスを実装できます。一方、クラスは他のクラスから継承したり、拡張したりすることができ、一般にオブジェクト指向プログラミングの概念をカバーするのに理想的です。
  • 構文: レコードの構文は、1 行で定義できるため、クラスの構文よりも単純です。一方、クラスには数行のコードが必要です。
  • 目的: レコードはDTO (データ転送オブジェクト)に似た構造です。つまり、不変データのモデル化に役立つクラスであり、その部分はクラスです。 ] は、動作と状態を持つことができるより一般的な構造です。

いつレコードを使用し、いつクラスを使用するのでしょうか?

必要なのはデータを保存するための不変のデータ構造であり、属性を変更する必要がない場合 (単に情報を運ぶオブジェクトとして見なされます)。一方、独自のロジックと特定のメソッドを備えたより一般的な構造、オブジェクト指向パラダイムへのアプローチ、デザイン パターンの適用、JPA や Hibernate の操作などが必要な場合は、 class を使用する必要があります。

追加: 可変属性を持つレコード

次の例を考えてみましょう。属性名と価格を持つ Product という 2 つのレコードと、ArrayList 型の 1 つの属性 products を持つ Cart と、製品の数とカートの合計を取得するいくつかのメソッドがあります。

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();
    }
}

この場合の問題は、各 レコード はそれ自体では不変ですが、レコード 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());
    }
}

リストの内容のみが変更され、products 属性自体は変更されていないため、上記のコードは問題なくコンパイルされます。これは特定のケースの単なる例であり、おそらく必須ではありませんが、これが可能であることを知っておくと良いでしょう。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/asjordi/records-vs-clases-en-java-1bb6?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3