Java の records をすでに知っている場合は、その使用法がクラスの使用法と非常に似ていることに気づくかもしれませんが、考慮する必要がある重要な違いがあります。この記事では、Java の records と classes の違いを見ていきます。 レコードをまだ知らない場合は、私の投稿「Java のレコード: レコードの内容とその使用方法」を読むことをお勧めします。
不変オブジェクトとは、オブジェクトの作成後にその属性を変更できないオブジェクトです。 records の場合、これらは不変です。つまり、タイプ record のオブジェクトが作成されると、その属性は変更できません。一方、クラスは実装方法に応じて不変である場合とそうでない場合があります。この部分はデータの整合性を保証し、誤って変更されることを防ぎます。
クラスは通常、データベース クエリからのデータやフォームからのデータなど、単にデータを保存するために作成されます。多くの場合、同期を使用せずにデータの有効性を保証する必要があるため、このデータは不変です。これを実現するには、次の要素を使用してクラスを作成します:
たとえば、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 メソッドが自動的に生成されます。
必要なのはデータを保存するための不変のデータ構造であり、属性を変更する必要がない場合 (単に情報を運ぶオブジェクトとして見なされます)。一方、独自のロジックと特定のメソッドを備えたより一般的な構造、オブジェクト指向パラダイムへのアプローチ、デザイン パターンの適用、JPA や Hibernate の操作などが必要な場合は、 class を使用する必要があります。
次の例を考えてみましょう。属性名と価格を持つ Product という 2 つのレコードと、ArrayList
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(Listproducts) { 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 属性自体は変更されていないため、上記のコードは問題なくコンパイルされます。これは特定のケースの単なる例であり、おそらく必須ではありませんが、これが可能であることを知っておくと良いでしょう。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3