I have 2 classes, where parent needs some property from child class while building. Is there a way to support this using lombok builders?
Parent.java
import lombok.Builder;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public abstract class Parent {
@Builder.Default
private String requestType = getRequestTypeFromSubclass();
abstract String getRequestTypeFromSubclass();
}
Child.java
import lombok.Builder;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import java.util.List;
@Getter
@SuperBuilder
public class Child extends Parent {
@Override
String getRequestTypeFromSubclass() {
return "Child1";
}
}
The above fails in compilation with message
error: non-static method getRequestType() cannot be referenced from a static context @SuperBuilder
As suggested in Baeldung use toBuilder=true
and remove @Builder.Default
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder(toBuilder=true)
public abstract class Parent {
private String requestType = getRequestType();
abstract String getRequestType();
}
With this, we can get rid of the double initialization
Change calling builder using toBuilder
, Child:
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public class Child extends Parent {
@Override
String getRequestType() {
return "Child1";
}
public static void main(String[] args) {
Child child = Child.builder().build();
System.out.println(child.getRequestType());
}
}
Builder.Default
is defined in static scope and expression might not able to resolve the abstract method implementation.
Probably you want to try this instead:
@Getter
@SuperBuilder
public abstract class Parent {
private String reqType;
abstract String getRequestType();
public String getReqType() {
return Objects.isNull(reqType) ? getRequestType() : reqType;
}
}
Override the property method with different method name from actual attribute getter method and should resolve the issue.
Try with:
Parent parent = Child.builder().build();
While lombok is a great tool for many things, in this very instance, you might want to avoid usign the builder pattern. The effect you desire (accessing a child's method at parent-initialization time is possible inside of standard POJO constructors. The following works for me:
@Getter
public abstract class Parent {
private String requestType = defineRequestType();
protected abstract String defineRequestType();
}
@Getter
public class Child extends Parent {
protected String defineRequestType() {
return "child1";
}
}
and the following test case:
@Test
public void test_lombokBuilderPolymorphism() {
Child child1 = new Child();
assertEquals("child1", child1.getRequestType());
}
So unless you definitely require the builder pattern for some other reasons, the default POJO's capabilities seem to be enough here.
On a side note: You should name the defining method other than get...
so it does not collide with the generated getter ( getRequestType
).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.