![](/img/trans.png)
[英]Deserialization Error in spark using immutable class with java (+ lombok)
[英]Update an immutable object with Lombok in Java?
我有一個域 class Person
用 Lombok @Value
注釋,因此將其標記為不可變,有 3 個字段。
在我的服務層中,我正在調用存儲庫以檢查此人是否存在。
如果確實存在,我需要從數據庫中獲取Person
object 並更新money
字段。
由於它是不可變的,因此無法做到這一點。 我正在閱讀一些文章並發現這可以使用構建器模式來完成。
我可能需要在我的Person
class 中創建一個updatePerson()
但不知道該怎么做。 還是我需要做其他事情?
Person.java
:
@Value
@Builder
public class Person {
private final UUID id;
private final String job;
private final BigDecimal money;
}
我正在使用 Java 15。
您還可以使用 lombok 的另一個功能,它不需要您使用構建器。 它被稱為@With
並且使用此注釋將創建不可變的設置器,這意味着設置器返回一個新的 object ,除了您想要更改的屬性之外,它具有舊的屬性。
@Value
public class Person {
/* You don't need to write final if you are using @Value. Lombok will make the variables final for you.
In theory you do not even need to write private,
because Lombok makes variables private by default instead of package private.*/
private UUID id;
private String job;
@With
private BigDecimal money;
}
Person newPerson = person.withMoney(new Big decimal("10"));
一般來說,我不確定使 object 不可變是否真的是個好主意。 除了 UUID 之外的每個變量似乎都可能在未來發生變化。
使用Lombok
:
@Value
@Builder(toBuilder = true)
public class Person {
private final UUID id;
private final String job;
private final BigDecimal money;
}
personObjectFromDatabase.toBuilder().setMoney(...).build()
或者
在這種情況下,您可以使用Builder
模式:
public class Person {
private final UUID id;
private final String job;
private final BigDecimal money;
public static class PersonBuilder {
private UUID id;
private String job;
private BigDecimal money;
public PersonBuilder(Person defaultPerson){
this.id = defaultPerson.getId();
this.job = defaultPerson.getJob();
this.money = defaultPerson.getMoney();
}
public PersonBuilder withId(UUID id) {
this.id = UUID;
return this;
}
public PersonBuilder withJob(String job) {
this.job = job;
return this;
}
public PersonBuilder withMoney(BigDecimal money) {
this.money = money;
return this;
}
public Person build() {
return new Person(id, job, money);
}
}
}
像下面這樣使用這個構建器:
Person person = new Person.PersonBuilder(personObjectFromDatabase)
.withMoney(...)
.build();
或者
您可以創建一個copyWith()
方法:
public class Person {
...
public Person copyWith(BigDecimal money) {
return new Person(this.id, this.job, money);
}
}
class 是不可變的; 您永遠無法更改該 class 實例的值。
相反,您必須創建 class 的新實例。
不要寫生成器; 您已經在使用 Lombok,只需使用@Builder
注釋,Lombok 就會為您創建一個構建器。
編輯:您正在使用構建器注釋。 您正在尋找的解決方案似乎是這樣的:
您必須創建 class 的新實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.