Java lombok为默认生成器调用子类函数

Java lombok为默认生成器调用子类函数,java,builder,lombok,Java,Builder,Lombok,我有两个类,其中父类在构建时需要来自子类的一些属性。有没有一种方法可以使用lombok构建器来支持这一点 Parent.java import lombok.Builder; import lombok.Getter; import lombok.experimental.SuperBuilder; @Getter @SuperBuilder public abstract class Parent { @Builder.Default private String reque

我有两个类,其中父类在构建时需要来自子类的一些属性。有没有一种方法可以使用lombok构建器来支持这一点

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();
}
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";
    }
}

Child.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();
}
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";
    }
}

上面的编译失败,并显示消息

错误:无法从中引用非静态方法getRequestType() 静态上下文@SuperBuilder

使用
toBuilder=true
并删除
@Builder.Default

import lombok.Getter;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder(toBuilder=true)
public abstract class Parent {

    private String requestType = getRequestType();
    abstract String getRequestType();
}
这样,我们就可以摆脱双重初始化

使用
将调用生成器更改为builder
,子项:

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
是在静态范围中定义的,表达式可能无法解析抽象方法实现

您可能想试试这个:

@Getter
@SuperBuilder
public abstract class Parent {

    private String reqType;
    abstract String getRequestType();

    public String getReqType() {
        return Objects.isNull(reqType) ? getRequestType() : reqType;
    }
}
使用与实际属性getter方法不同的方法名重写属性方法,并应解决此问题

尝试:

Parent parent = Child.builder().build();

虽然lombok在很多方面都是一个很好的工具,但在这个例子中,您可能希望避免使用生成器模式。您想要的效果(在父级初始化时访问子级方法)可以在标准POJO构造函数中实现。 以下是我的作品:

@Getter
公共抽象类父类{
私有字符串requestType=defineRequestType();
受保护的抽象字符串defineRequestType();
}
@Getter
公共类子级扩展父级{
受保护的字符串defineRequestType(){
返回“child1”;
}
}
以及以下测试用例:

@测试
公共无效性检验_lombokBuilderPolymorphism(){
Child child1=新的Child();
assertEquals(“child1”,child1.getRequestType());
}
因此,除非您出于某些其他原因明确需要构建器模式,否则缺省POJO的功能在这里似乎就足够了


另请注意:您应该为定义方法命名,而不是
get…
,这样它就不会与生成的getter冲突(
getRequestType
).

这是一个问题,一直到Java中是否应该有
抽象静态方法的问题。我相信这样的情况证明了这一概念的正确性,但Java的一般前提似乎仍然是“多态性是对象派生的特征,而不是类派生”。(尚未给出答案,但我会检查)。上述内容不用于日常工作,其中一个用例是在执行jackson序列化时使用的。子类是根据requestType键选择的。@TreffnonX what's
defineRequestType()
?是否删除了
@Builder.Default
?我没有删除@Builder.Default over defineRequestType。也就是说,代码现在在运行时失败。
@test public void test\u lombokBuilderPolymorphism(){Child child1=Child.Builder().build();assertEquals(“child1”,child1.getRequestType());}的测试用例
在断言时失败:
应为:但为:
更改为
new Child().toBuilder().build()
Hmm…这行代码根本不适合我。我想我做错了什么。我开始理解这个概念。但是我不知怎么地觉得,使用init方法可能会对OP有更好的帮助…另外,我必须写:
Child child1=new Child(Child.builder()).toBuilder().build()
甚至可以编译它。但它在运行时会产生相同的结果。是的,这对我不起作用。没有.toBuilder()。@user7294900您能同时发布父级和子级吗?