如果您已经了解 Java 中的 records,您可能会发现它的用法与类非常相似,但是有一些重要的差异必须考虑。在本文中,我们将了解 Java 中的 records 和 classes 之间的差异。如果您仍然不知道记录,我建议阅读我的帖子《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 等,那么您应该使用类。
让我们考虑以下示例,有两条记录 Product,其属性为名称和价格,还有 Cart,其具有 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(); } }
这种情况下的问题是,每个 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()); } }
上面的代码编译没有问题,因为只修改了列表的内容,但产品属性本身没有被修改。这只是特定情况的示例,可能没有必要,但很高兴知道可以这样做。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3