![](/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.