Java 使用SuperBuilder使用Lombok扩展父类
我有一个DTO使用Lombok功能,如下图所示。但现在由于一些要求,我不得不将我的DTO扩展到如下所示的父类。我如何对DTO进行最小的更改以支持该功能。我尝试使用@SuperBuilder注释,但失败了 DTO之前:Java 使用SuperBuilder使用Lombok扩展父类,java,spring-boot,java-8,lombok,dto,Java,Spring Boot,Java 8,Lombok,Dto,我有一个DTO使用Lombok功能,如下图所示。但现在由于一些要求,我不得不将我的DTO扩展到如下所示的父类。我如何对DTO进行最小的更改以支持该功能。我尝试使用@SuperBuilder注释,但失败了 DTO之前: @Getter @ToString @EqualsAndHashCode @Builder(toBuilder = true) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class RequestMessage
@Getter
@ToString
@EqualsAndHashCode
@Builder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage {
private final String name;
}
需要扩展的父类
@Data
@SuperBuilder(toBuilder = true)
@JsonDeserialize(builder = MyDTO.Builder.class)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
@JsonPOJOBuilder(withPrefix = "")
protected abstract static class Builder<T extends MyDTO, B extends Builder<T, B>> {
protected T dtoInstance;
protected B builderInstance;
public Builder() {
dtoInstance = createDtoInstance();
builderInstance = returnBuilderInstance();
}
protected abstract T createDtoInstance();
protected abstract B returnBuilderInstance();
public B myAccountId(String accountId) {
dtoInstance.myAccountId = accountId;
return builderInstance;
}
public T build() {
return dtoInstance;
}
}
}
我的尝试如下所示:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
// TODO Auto-generated method stub
return null;
}
}
您不应该将lombok
@Builder
与静态内部构建器类混合使用。如果可以摆脱Builder
类,那么下一个代码应该可以工作
请求消息:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
MyDTO:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
测试:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
您不应该将lombok
@Builder
与静态内部构建器类混合使用。如果可以摆脱Builder
类,那么下一个代码应该可以工作
请求消息:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
MyDTO:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
测试:
@Getter
@ToString
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class RequestMessage extends MyDTO {
private final String name;
@Override
public String emitSerializedPayload() throws JsonProcessingException {
return null;
}
public RequestMessage(String myAccountId, String name) {
super(myAccountId);
this.name = name;
}
}
@Data
@SuperBuilder(toBuilder = true)
public abstract class MyDTO implements Serializable {
@JsonIgnore private final ObjectMapper objectMapper = new ObjectMapper();
protected String myAccountId;
protected MyDTO() {}
public MyDTO(String myAccountId) {
this.myAccountId = myAccountId;
}
public static int hashCode(Object... objects) {
return Arrays.deepHashCode(objects);
}
public static boolean equal(Object o1, Object o2) {
// implementation of equals method
return false;
}
public abstract String emitSerializedPayload() throws JsonProcessingException;
}
@Test
void name() {
String myName = "myName";
String myAccountId = "myAccountId";
var request = RequestMessage.builder().name(myName).myAccountId(myAccountId).build();
System.out.println("request = " + request);
RequestMessage requestMessage = new RequestMessage(myAccountId, myName);
}
您应该尝试将
@Builder
或@SuperBuilder
注释添加到父类中,我也这样做了@SuperBuilder(toBuilder=true),但它不起作用,我更新了父类。您不应该将lombok@Builder
与静态内部类生成器混合使用。在您的情况下,最简单的方法是重构父类,并用@SuperBuilder(toBuilder=true)
注释替换Builder
类。它给出的错误是,RequestMessage.Builder无法解析为类型。请在此代码行中的RequestMessage.Builder().name(myName).myAccountId(myAcId).build()类型中创建类生成器;您应该使用.builder()
而不是.builder()
您应该尝试将@builder
或@SuperBuilder
注释添加到父类中,我也这样做了@SuperBuilder(toBuilder=true),但它不起作用,我更新了父类。您不应该将lombok@Builder
与静态内部类生成器混合使用。在您的情况下,最简单的方法是重构父类,并用@SuperBuilder(toBuilder=true)
注释替换Builder
类。它给出的错误是,RequestMessage.Builder无法解析为类型。请在此代码行中的RequestMessage.Builder().name(myName).myAccountId(myAcId).build()类型中创建类生成器;您应该使用.builder()
而不是.builder()
好的,我正在尝试用new实例化它,即new RequestMessage.builder().name(myName).myAccountId(myAccountId).build()我不能使用new吗?equals和hashcode(callSuper=true)之间应该有什么区别和以前一样,我只是使用EqualsAndHashCode。所以我可以继续使用相同的或应该执行callSuper=true。new
关键字与生成器模式无关。如果您想使用它,您需要在父类中声明一个构造函数,然后在子构造函数中使用它(调用(super()
)。根据文档:lombok.equalsAndHashCode.callSuper=[call | skip | warn](默认值:warn)如果设置为call,lombok将生成对hashCode的超类实现的调用,如果您的类扩展了某些内容,则将生成equals。如果设置为skip,则不会生成此类调用。默认行为类似于skip,并带有一个附加警告。好的,我正试图用new(即new Req)实例化它uestMessage.builder().name(myName).myAccountId(myAccountId).build()我不能使用new吗?EqualsAndHashCode(callSuper=true)之间应该有什么区别还有EqualsAndHashCode。和以前一样,我只是使用EqualsAndHashCode。我可以继续使用相同的还是应该使用callSuper=true。new
关键字与生成器模式无关。如果要使用它,需要在父类中声明一个构造函数,然后使用它(调用(super()
)在子构造函数中。根据docs:lombok.equalsAndHashCode.callSuper=[call | skip | warn](默认值:warn)如果设置为call,lombok将生成对hashCode的超类实现的调用,如果您的类扩展了某些内容,则会生成相等的调用。如果设置为skip,则不会生成此类调用。默认行为类似于skip,并带有附加警告。