我尝试对具有注释@SuperBuilder
的类使用继承。我有一个超类:
@SuperBuilder
@Data
public class BaseClass {
private String userID;
private String clientID;
}
以及扩展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");
}
当我尝试为类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
,因为继承关系的方向相反,因为它反映了带注释类之间的关系:UserWithNameBuilder extends BaseClassBuilder
,如UserWithName extends BaseClass
。
因此,无法调用要构建的类的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方法,每个方法都可以设置不同的值。
请注意,您也可以将此/这些方法直接包含在BaseClassBuilder
中。StackOverflow上有一些问题和答案,讨论自定义@SuperBuilder
。