当前位置: 首页 > 知识库问答 >
问题:

java-使用泛型将子类生成器初始化为父类生成器的类型

归俊捷
2023-03-14

我在父类和子类中都有构建器。父对象有一个抽象生成器和一个扩展抽象生成器的具体生成器。子级有一个扩展父级抽象生成器的抽象生成器和一个扩展子级抽象生成器的具体生成器。原因是父级的setter返回当前的Builder类。我有一些方法返回类自己的抽象构建器类型,我想将其称为父抽象类型(调用它的父方法)。我所能做的就是ParentBuilder

我想在主代码中执行的操作:

ParentBuilder<? extends ParentBuilder<?> builder; // How to do this?
if (something) {
    builder = Child.doSomething();
}
else {
    builder = new Parent.builder();
}

Parent p = builder.setThing1("foo").build();

在Parent.java

public class Parent {

    private final String thing1;

    protected <B extends ParentBuilder<B>> Parent(final B builder) {
        this.thing1 = builder.thing1;
    }

    public String getThing1() {
        return this.thing1;
    }

    protected abstract static class ParentBuilder<B extends ParentBuilder<B>> {
        protected final Class<B> builderClass;
        protected String thing1;

        protected ParentBuilder(final Class<B> builderClass) {
            this.builderClass = builderClass;
        }

        public B setThing1(final String thing1) {
            this.thing1 = thing1;
            return builderClass.cast(this);
        }

        public abstract Parent build();
    }

    public static class Builder extends ParentBuilder<Builder> {
        public Builder() {
            super(Builder.class);
        }

        @Override
        public Parent build() {
            return new Parent(this);
        }
    }
}

在孩子身上。JAVA

public class Child extends Parent {

    private final String thing2;

    protected <B extends ChildBuilder<B>> Child(final B builder) {
        super(builder);
        this.thing2 = builder.thing2;
    }

    public String getThing2() {
        return this.thing2;
    }

    public static Builder doThings(/*...*/) {
        //...
        return new Child.Builder();
    }

    protected abstract static class ChildBuilder<B extends ParentBuilder<B>> extends ParentBuilder<B> {
        protected String thing2;

        protected ChildBuilder(final Class<B> builderClass) {
            super(builderClass);
        }

        public B setThing2(final String thing2) {
            this.thing2 = thing2;
            return builderClass.cast(this);
        }
    }

    public static class Builder extends ChildBuilder<Builder> {
        public Builder() {
            super(Builder.class);
        }

        @Override
        public Child build() {
            return new Child(this);
        }
    }
}

在第一节中,我将构建器声明为父抽象构建器类型,但我不确定键入该对象的正确方式。通配符似乎不对。我想到的一个选择是在抽象构建器之上创建一个接口,然后我可以使用这种类型。但有接口似乎很麻烦-


共有1个答案

岳英锐
2023-03-14

以下是您的设置的工作代码:

Parent.ParentBuilder<?> builder; 

if ( something ) {
    builder = new Child.Builder();
}
else {
    builder = new Parent.Builder();
}

Parent p = builder.setThing1("foo").build();

现在,如果您希望builder.build()返回而不进行强制转换,您需要更改现有的生成器泛型类型声明

 类似资料:
  • 我正在尝试使用以下方法在运行时获取Avro模式: 但由于我的POJO类包含以下泛型: 我得到以下例外情况: 我知道Avro不会支持泛型类型。是否有一种方法可以在运行时生成架构时从类中省略某些类字段?

  • 问题内容: 因此,我正在开发这个通用的HashTable类,并且希望将其通用地用于任何数量的传入类型,并且我还想将内部存储数组初始化为LinkedList的数组(出于冲突目的),其中为确保类型安全,每个LinkedList都被预先指定为HashTable类中的泛型类型。我该怎么做?以下代码最能阐明我的意图,但当然不会编译。 问题答案: Java中的泛型不允许创建具有泛型类型的数组。您可以将数组转换

  • 如何为动态创建的函数声明泛型类型? 我如何在中使用并传递? < code>useFoo的预期用法

  • Spring4包含了对泛型类型解析的主要增强,但当包含bean类的type参数被参数化时,我无法自动生成泛型类型。 我需要跟踪提交给外部服务的作业的状态,并且我想在每个作业启动时为其创建一个条目,并在收到回发时清除或更新它。我通常会尝试将持久性策略与服务接口分开,因此我有一个接口,一个Spring数据Mongo类。由于作业可能会在外部服务有机会为其分配ID(例如HTTP 502)之前失败,因此我需

  • 问题内容: 我正在尝试创建UIBezierPath的子类,以添加一些对我有用的属性。 编辑:我需要这个,因为在我的代码中我写 并导致编译错误: “必须调用超类’UIBezierPath’的指定初始化程序” 我试图在子类中添加该初始化器,但似乎不起作用。 你能帮我吗? 问题答案: 注意 :此问题已在iOS 9中得以解决,在该版本中,API已被重写为存在,其他所有(方便初始化程序)也是如此。 问题 简

  • 将Android Studio升级到4.0版本后,在“gradle-wrapper.properties”中: