@Builder Lombok - 继承
@Builder Lombok - Inheritance
我尝试对具有注释 @SuperBuilder
的 class 使用继承。
我有一个超级class:
@SuperBuilder
@Data
public class BaseClass {
private String userID;
private String clientID;
}
还有两个 class 扩展 BaseClass
:
@SuperBuilder
@Data
public class UserWithName extends BaseClass {
private String name;
}
并且:
@SuperBuilder
@Data
public class UserWithNumber extends BaseClass {
private int number;
}
之后,我尝试创建一些 BaseBuilder
:
public BaseClass.BaseClassBuilder generateBaseBuilder() {
return BaseClass.builder()
.userID("1")
.clientID("1");
}
我想在尝试为 classes UserWithName
和 UserWithNumber
创建对象时使用基础构建器。我试着这样做:
public UserWithName generateUserWithName(String name) {
UserWithName.UserWithNameBuilder builder = (UserWithName.UserWithNameBuilder) generateBaseBuilder();
return builder
.name(name)
.build();
}
但它不起作用 (ClassCastException
)。这是完整的代码:
public class Main {
@SuperBuilder
@Data
public static class BaseClass {
private String userID;
private String clientID;
}
@SuperBuilder
@Data
public static class UserWithName extends BaseClass {
private String name;
}
@SuperBuilder
@Data
public static class UserWithNumber extends BaseClass {
private int number;
}
public BaseClass.BaseClassBuilder generateBaseBuilder() {
return BaseClass.builder()
.userID("1")
.clientID("1");
}
public UserWithName generateUserWithName(String name) {
UserWithName.UserWithNameBuilder builder = (UserWithName.UserWithNameBuilder) generateBaseBuilder();
return builder
.name(name)
.build();
}
}
有没有什么方法可以使用我的方法 generateBaseBuilder()
创建我的对象?
您不能将 BaseClassBuilder
的实例转换为 UserWithNameBuilder
,因为继承关系是相反的,因为它反映了带注释的 class 之间的关系:UserWithNameBuilder extends BaseClassBuilder
,比如 UserWithName extends BaseClass
.
因此,无法调用您要构建的 class 的 builder()
方法。
话虽如此,我猜您的 generateBaseBuilder()
方法的主要目的不是创建生成器,而是为新实例设置一些默认值。有两种方法可以实现:
向您的字段添加默认值(作为字段初始值设定项)并在其上添加 @Builder.Default
。
重写您的 generateBaseBuilder
方法,使其成为 setDefaultValues
,它将构建器实例作为参数并仅设置这些值:
public static <T extends BaseClass.BaseClassBuilder<?, ?>> T setDefaultValues(T builder) {
builder
.userID("1")
.clientID("1");
return builder;
}
public static UserWithName generateUserWithName(String name) {
UserWithNameBuilder<?,?> builder = setDefaultValues(UserWithName.builder());
return builder
.name(name)
.build();
}
我更喜欢第一个选项,因为它更简洁。但是,第二个选项更灵活,因为您可以有多个这样的 setValues 方法,每个方法都可以设置不同的值。
请注意,您还可以将 this/these 方法直接包含到 BaseClassBuilder
中。 Whosebug 上有一些讨论自定义 @SuperBuilder
.
的问题和答案
我尝试对具有注释 @SuperBuilder
的 class 使用继承。
我有一个超级class:
@SuperBuilder
@Data
public class BaseClass {
private String userID;
private String clientID;
}
还有两个 class 扩展 BaseClass
:
@SuperBuilder
@Data
public class UserWithName extends BaseClass {
private String name;
}
并且:
@SuperBuilder
@Data
public class UserWithNumber extends BaseClass {
private int number;
}
之后,我尝试创建一些 BaseBuilder
:
public BaseClass.BaseClassBuilder generateBaseBuilder() {
return BaseClass.builder()
.userID("1")
.clientID("1");
}
我想在尝试为 classes UserWithName
和 UserWithNumber
创建对象时使用基础构建器。我试着这样做:
public UserWithName generateUserWithName(String name) {
UserWithName.UserWithNameBuilder builder = (UserWithName.UserWithNameBuilder) generateBaseBuilder();
return builder
.name(name)
.build();
}
但它不起作用 (ClassCastException
)。这是完整的代码:
public class Main {
@SuperBuilder
@Data
public static class BaseClass {
private String userID;
private String clientID;
}
@SuperBuilder
@Data
public static class UserWithName extends BaseClass {
private String name;
}
@SuperBuilder
@Data
public static class UserWithNumber extends BaseClass {
private int number;
}
public BaseClass.BaseClassBuilder generateBaseBuilder() {
return BaseClass.builder()
.userID("1")
.clientID("1");
}
public UserWithName generateUserWithName(String name) {
UserWithName.UserWithNameBuilder builder = (UserWithName.UserWithNameBuilder) generateBaseBuilder();
return builder
.name(name)
.build();
}
}
有没有什么方法可以使用我的方法 generateBaseBuilder()
创建我的对象?
您不能将 BaseClassBuilder
的实例转换为 UserWithNameBuilder
,因为继承关系是相反的,因为它反映了带注释的 class 之间的关系:UserWithNameBuilder extends BaseClassBuilder
,比如 UserWithName extends BaseClass
.
因此,无法调用您要构建的 class 的 builder()
方法。
话虽如此,我猜您的 generateBaseBuilder()
方法的主要目的不是创建生成器,而是为新实例设置一些默认值。有两种方法可以实现:
向您的字段添加默认值(作为字段初始值设定项)并在其上添加
@Builder.Default
。重写您的
generateBaseBuilder
方法,使其成为setDefaultValues
,它将构建器实例作为参数并仅设置这些值:
public static <T extends BaseClass.BaseClassBuilder<?, ?>> T setDefaultValues(T builder) {
builder
.userID("1")
.clientID("1");
return builder;
}
public static UserWithName generateUserWithName(String name) {
UserWithNameBuilder<?,?> builder = setDefaultValues(UserWithName.builder());
return builder
.name(name)
.build();
}
我更喜欢第一个选项,因为它更简洁。但是,第二个选项更灵活,因为您可以有多个这样的 setValues 方法,每个方法都可以设置不同的值。
请注意,您还可以将 this/these 方法直接包含到 BaseClassBuilder
中。 Whosebug 上有一些讨论自定义 @SuperBuilder
.