英文:
Lombok's builder with mandatory parameters
问题
If I add @Builder to a class. The builder method is created.
如果我给一个类添加@Builder注解,将会生成一个构建器方法。
I have a requirement where a particular field is mandatory. In this case, the name field is mandatory. Ideally, I would like to declare it like so.
我有一个要求,其中一个特定字段是必需的。在这种情况下,name字段是必需的。理想情况下,我想这样声明。
When googling i found many alternatives like overriding the builder implementation as below:
在进行谷歌搜索时,我发现了许多替代方法,比如重写构建器的实现如下:
And then use it like below:
然后像下面这样使用它:
The problem with above approach is that it still provides the name() and PersonBuilder() method like below, which i don't want:
上述方法的问题在于它仍然提供了像下面这样的name()和PersonBuilder()方法,而我不想要:
Another approach is to add @lombok.nonnull check at name which will force to provide value for name while creating object. but it is a runtime check. it will not force me to provide value for name while creating object.
另一种方法是在name上添加@lombok.nonnull检查,它将强制在创建对象时为name提供值。但这是一个运行时检查,它不会强制我在创建对象时为name提供值。
Is there any additional technique which lombok provides to achieve below:
是否有额外的技术可以使用 lombok 来实现以下目标:
Note: The builder() and name() should not be exposed. The only way to create Person object should be either above or below:
注意:不应该暴露builder()和name()方法。创建Person对象的唯一方式应该是上面或下面的方式:
英文:
If I add @Builder to a class. The builder method is created.
Person.builder().name("john").surname("Smith").build();
I have a requirement where a particular field is mandatory. In this case, the name field is mandatory. Ideally, I would like to declare it like so.
Person.builder("john").surname("Smith").build();
When googling i found many alternatives like overriding the builder implementation as below:
@Builder
public class Person {
private String name;
private String surname;
public static PersonBuilder builder(String name) {
return new PersonBuilder().name(name);
}
}
And then use it like below:
Person p = Person.builder("Name").surname("Surname").build();
The problem with above approach is that it still provides the name() and PersonBuilder() method like below, which i don't want:
Person p = Person.builder("Name").surname("Surname").name("").build();
Person p = new Person.PersonBuilder().build;
Another approach is to add @lombok.nonnull check at name which will force to provide value for name while creating object. but it is a runtime check. it will not force me to provide value for name while creating object.
Is there any additional technique which lombok provides to achieve below:
Person p = Person.builder("Name").surname("Surname").build();
Note: The builder() and name() should not be exposed. The only way to create Person object should be either above or below:
Person p = Person.builder("Name").build();
答案1
得分: 3
你不能真的用Lombok来做到这一点,参见库作者的解释。但是自己编写这个构建器是否很复杂呢?
public static class PersonBuilder {
private final String name;
private String surname;
PersonBuilder(String name) {
this.name = name;
}
public PersonBuilder surname(String surname) {
this.surname = surname;
return this;
}
public Person build() {
return new Person(name, surname);
}
}
使用你已经拥有的相同方法:
public static PersonBuilder builder(String name) {
return new PersonBuilder(name);
}
英文:
You can't really do it with lombok, see the explanation from the library authors. But is it that complicated to roll this builder on your own?
public static class PersonBuilder {
private final String name;
private String surname;
PersonBuilder(String name) {
this.name = name;
}
public PersonBuilder surname(String surname) {
this.surname = surname;
return this;
}
public Person build() {
return new Person(name, surname);
}
}
with the same method that you already have:
public static PersonBuilder builder(String name) {
return new PersonBuilder(name);
}
答案2
得分: 1
尝试将构建器设置为私有。
我相当确定,一旦再次阅读该线程,您就会找到答案。
附言:如果您的类只有两个字段,最好直接使用构造函数。
英文:
Try to make the builder private.
Did you check this comment https://stackoverflow.com/questions/29885428/required-arguments-with-a-lombok-builder#comment103350941_30867286
I am pretty sure you will find out once read the thread one more time.
P.S. If you have a class with only two field better use directly a constructor.
答案3
得分: 0
最佳实践:
import lombok.Builder;
import lombok.NonNull;
@Builder(builderMethodName = "privateBuilder")
public class Person {
@NonNull
private String name;
private String surname;
public static class PersonNameBuilder {
public PersonBuilder name(String name) {
return Person.privateBuilder().name(name);
}
}
private static class PersonExtraBuilder extends PersonBuilder {
@Deprecated
@Override
public PersonBuilder name(String name) {
return this;
}
}
public static PersonNameBuilder builder(String name) {
return new PersonNameBuilder();
}
private static PersonExtraBuilder privateBuilder() {
return new PersonExtraBuilder();
}
}
用法:
PersonNameBuilder nameBuilder = Person.builder();
PersonBuilder builder = nameBuilder.name("John");
Person p1 = builder.surname("Smith").build();
// Or
Person p2 = Person.builder().name("John").surname("Smith").build();
// The last `.name("")` will not work, and it will be marked as Deprecated by IDE.
Person p3 = Person.builder().name("John").surname("Smith").name("").build();
英文:
Best Practice:
import lombok.Builder;
import lombok.NonNull;
@Builder(builderMethodName = "privateBuilder")
public class Person {
@NonNull
private String name;
private String surname;
public static class PersonNameBuilder {
public PersonBuilder name(String name) {
return Person.privateBuilder().name(name);
}
}
private static class PersonExtraBuilder extends PersonBuilder{
@Deprecated
@Override
public PersonBuilder name(String name) {
return this;
}
}
public static PersonNameBuilder builder(String name) {
return new PersonNameBuilder();
}
private static PersonExtraBuilder privateBuilder(){
return new PersonExtraBuilder();
}
}
Usage:
PersonNameBuilder nameBuilder = Person.builder();
PersonBuilder builder = nameBuilder.name("John");
Person p1 = builder.surname("Smith").build();
// Or
Person p2 = Person.builder().name("John").surname("Smith").build();
// The last `.name("")` will not work, and it will be marked as Deprecated by IDE.
Person p3 = Person.builder().name("John").surname("Smith").name("").build();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论