如果您已經了解 Java 中的 records,您可能會發現它的用法與類別非常相似,但必須考慮到一些重要的差異。在本文中,我們將了解 Java 中記錄和類別之間的差異。如果您仍然不知道記錄,我建議閱讀我的文章《Java 中的記錄:它們是什麼以及如何使用它們》。
不可變對像是指一旦建立對象,其屬性就無法修改的對象。對於 records 來說,它們是不可變的,也就是說,一旦創建 record 類型的對象,其屬性就無法修改。另一方面,類別可能是不變的,也可能不是不變的,這取決於它的實作方式。這部分確保資料的完整性並防止其被意外修改。
類別通常只是為了儲存資料而編寫,例如來自資料庫查詢的資料或來自表單的資料。在許多情況下,該數據是不可變的,因為需要在不使用同步的情況下確保數據的有效性。為了實現這一點,使用以下元素編寫一個類別:
例如,如果你有一個 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 方法。
如果需要的是一個不可變的資料結構來儲存數據,並且不需要對屬性進行修改(簡單地看成是一個攜帶資訊的物件)。另一方面,如果您需要一個具有獨特邏輯和特定方法的更通用的結構、一種物件導向範例的方法、應用設計模式或使用 JPA 或 Hibernate 等,那麼您應該使用類別。
Consideremos el siguiente ejemplo, se tienen dos records Product con los atributos name y price, y Cart con un solo atributo products del tipo 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(List<Product> products) { public Cart() { this(new ArrayList<>()); } public int getQuantity() { return this.products.size(); } public double getTotal() { return this.products.stream().mapToDouble(Product::price).sum(); } }
La cuestión en este caso es que cada uno de los record es inmutable por sí mismo, pero en el caso del record Cart al tener un atributo del tipo ArrayList<> y dado que por naturaleza un ArrayList es mutable, se puede modificar el contenido de la lista una vez que se crea una instancia del record 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()); } }
El código anterior compila sin problemas, ya que solo se está modificando el contenido de la lista, pero no se está modificando el atributo products en sí. Este solo es un ejemplo para un caso particular, que probablemente no sea necesario, pero es bueno saber que esto se puede realizar.
以上是Java 中的记录与类的详细内容。更多信息请关注PHP中文网其他相关文章!