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中文網其他相關文章!