record 是一种结构体,其特点是不可变,也就是说,一旦创建了 record 类型的对象,它的属性无法修改,它相当于其他编程语言所说的data-class或DTO(数据传输对象)。但是,如果需要使用 setter 方法修改某个属性,并且考虑到记录中的每个属性都是 Final 类型,那么如何实现呢?
为了证明这是否可行,让我们创建一个具有名称和价格两个属性的记录 Product,以及在 Java 中定义记录时自动创建的相应方法:
public record Product(String name, double price) { }
现在,如果你创建一个 Product 类型的对象并尝试修改 name 属性,你会发现这是不可能的,甚至没有 setter 方法来做到这一点:
Product p = new Product("Bread", 1.0); p.setName("Water"); // Error: cannot resolve method 'setName' in 'Product'
但是,如果我们知道记录可以有其他方法,那么我们可以创建一个setName(String name)方法来修改name属性并为其分配新值,因为答案是否定的. ,它不像普通课堂那样工作,例如:
public record Product(String name, double price) { // Error: cannot asign a value to final variable 'name' public void setName(String name) { this.name = name; } }
那么如何在Java中修改记录的属性呢?答案是,如果 set 方法返回 record 的新实例及其每个属性,并且显然带有修改后的属性,则可以。这个过程可能有点乏味,具体取决于记录具有的属性数量。
public record Product(String name, double price) { public Product setName(String name) { return new Product(name, this.price); } public Product setPrice(double price) { return new Product(this.name, price); } }
这样,当调用任何一个setter方法时,都会获得一个具有修改属性的Product类型的新实例,例如:
Product p = new Product("Bread", 1.0); Product q = p.setName("Milk"); Product r = q.setPrice(2.0);
对于每个对象 p、q 和 r,其 get、equals、hashCode 和 toString 方法都可以正常调用,考虑到没有一个对象彼此相等,因为每个对象的属性值都不同。
public class Main { public static void main(String[] args) { Product p = new Product("Bread", 1.0); Product q = p.setName("Milk"); Product r = q.setPrice(2.0); System.out.println(p); // Product[name=Bread, price=1.0] System.out.println(q); // Product[name=Milk, price=1.0] System.out.println(r); // Product[name=Milk, price=2.0] System.out.println(p.equals(q)); // false System.out.println(q.equals(r)); // false System.out.println(r.equals(p)); // false } }
此时,考虑到记录被设计为一种允许以简单的方式存储和传输信息的结构,考虑这种方法是否适合要解决的问题非常重要。在应用程序中的方式并且是不可变的,或者如果需要具有更大灵活性的结构,那么应该使用 class 。有关何时使用记录或类的更多信息,您可以参考以下帖子。
以上是Java 中的 Setters 和 Record的详细内容。更多信息请关注PHP中文网其他相关文章!