繁体   English   中英

用 Java 中的 Lombok 更新不可变的 object?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM