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