简体   繁体   中英

lombok call child class function for default builder

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.

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