[英]How to build an object when we have inheritance relationship using lombok builder?
In my project, I am using lombok to avoid writing getters and setters for a class. 在我的项目中,我使用lombok来避免为一个类编写getter和setter。 Also, I am using lombok.Builder to build an object instead of writing new Obeject() and then setting all the values.
此外,我使用lombok.Builder来构建一个对象,而不是编写新的Obeject(),然后设置所有的值。
But when we have inheritance relationship and when we want to construct child object using lombok builder, I am not getting parent's field. 但是当我们有继承关系并且当我们想要使用lombok builder构建子对象时,我没有得到父类的字段。
For example: 例如:
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class Parent{
private String nationality;
.
.
// more columns
}
And Child class would be something like this: 而Child类将是这样的:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Child extends Parent{
private String firstName;
private String lastName;
.
.
}
In my test class, where I need to build child object 在我的测试类中,我需要构建子对象
public class Test{
public void testMethod(){
Child child = Child.builder()
.firstName("Rakesh")
.lastName("SS")
.nationality("some text")// I am not able to set nationality
.build();
}
}
Please let me know, is there any way to handle this scenario in lombok. 请让我知道,有没有办法在lombok中处理这种情况。
@Builder
has no way to determine which fields of Parent
you wish to expose. @Builder
无法确定您希望公开哪个Parent
字段。
When @Builder
is placed on a class, only fields explicitly declared on that class are added to the *Builder
. 将
@Builder
放在类上时,只有在该类上显式声明的字段才会添加到*Builder
。
When @Builder
is placed on a static method or a constructor the resulting *Builder
will have a method for each argument. 当
@Builder
放置在静态方法或构造函数上时,生成的*Builder
将为每个参数提供一个方法。
Also if you are using @Builder
then is it safe to assume that at least Child
is meant to be immutable? 此外,如果您使用
@Builder
那么可以安全地假设至少Child
是不可变的吗?
I supply two examples, one where Parent
is mutable and Child
is immutable and one where both Parent
and Child
are immutable. 我提供了两个例子,一个是
Parent
是可变的, Child
是不可变的,另一个是Parent
和Child
都是不可变的。
import static org.junit.Assert.*;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import lombok.experimental.NonFinal;
import org.junit.Test;
public class So32989562ValueTest {
@Value
@NonFinal
public static class Parent {
protected final String nationality;
}
@Value
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static class Child extends Parent {
private final String firstName;
private final String lastName;
@Builder(toBuilder = true)
private Child(String nationality, String firstName, String lastName) {
super(nationality);
this.firstName = firstName;
this.lastName = lastName;
}
}
@Test
public void testChildBuilder() {
String expectedFirstName = "Jeff";
String expectedLastName = "Maxwell";
String expectedNationality = "USA";
Child result = Child.builder()
.firstName(expectedFirstName)
.lastName(expectedLastName)
.nationality(expectedNationality)
.build();
assertEquals(result.toString(), expectedFirstName, result.getFirstName());
assertEquals(result.toString(), expectedLastName, result.getLastName());
assertEquals(result.toString(), expectedNationality, result.getNationality());
}
}
import static org.junit.Assert.*;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.Value;
import org.junit.Test;
public class So32989562DataTest {
@Data
public static class Parent {
protected String nationality;
}
@Value
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public static class Child extends Parent {
private final String firstName;
private final String lastName;
@Builder(toBuilder = true)
private Child(String nationality, String firstName, String lastName) {
this.setNationality(nationality);
this.firstName = firstName;
this.lastName = lastName;
}
}
@Test
public void testChildBuilder() {
String expectedFirstName = "Jeff";
String expectedLastName = "Maxwell";
String expectedNationality = "USA";
Child result = Child.builder()
.firstName(expectedFirstName)
.lastName(expectedLastName)
.nationality(expectedNationality)
.build();
assertEquals(result.toString(), expectedFirstName, result.getFirstName());
assertEquals(result.toString(), expectedLastName, result.getLastName());
assertEquals(result.toString(), expectedNationality, result.getNationality());
}
}
Above solution works, however that requires too much workaround. 以上解决方案有效,但需要太多的解决方法。 And further any changes in child and parent class requires changing constructor arguments everywhere.
而且,子类和父类的任何更改都需要在任何地方更改构造函数参数。
Lombok has introduced experimental features with version: 1.18.2 for inheritance issues faced with Builder annotation, and can be resolved with @SuperBuilder annotation as below. Lombok针对Builder注释面临的继承问题引入了版本:1.18.2的实验性功能,可以使用@SuperBuilder注释解决如下。
@SuperBuilder
public class ParentClass {
private final String a;
private final String b;
}
@SuperBuilder
public class ChildClass extends ParentClass{
private final String c;
}
Now, one can use Builder class as below (that was not possible with @Builder annotation) 现在,可以使用如下的Builder类(使用@Builder注释无法实现)
ChildClass.builder().a("testA").b("testB").c("testC").build();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.