@Builder龙目-继承



我尝试对具有注释@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");
}

当我尝试为类UserWithNameUserWithNumber创建对象时,我想使用基本生成器。我试着这样做:

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()方法的主要目的不是创建构建器,而是为新实例设置一些默认值。有两种方法可以实现这一点:

  1. 将默认值(作为字段初始值设定项(添加到字段中,并在其上放置@Builder.Default

  2. 重写您的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

最新更新