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'
但是,如果我们知道 record 可以有其他方法,那么我们可以创建一个 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 的新实例及其每个属性,并且显然带有修改后的属性,则可以。这个过程可能有点乏味,具体取决于 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方法时,都会获得一个带有modified属性的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。有关何时使用 record 或 class 的更多信息,您可以参考以下帖子。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3