Can I have an abstract builder class in java with method chaining without doing unsafe operations?

ε祈祈猫儿з 提交于 2019-12-02 17:33:33

You want to declare T as extends AbstractBuilder<T> in AbstractBuilder.

Use an abstract protected method to get this of type T.

abstract class AbstractBuilder<T extends AbstractBuilder<T>> {
    protected abstract T getThis();

    public T foo() {
        // set some property
        return getThis();
    }
}


class TheBuilder extends AbstractBuilder<TheBuilder> {
    @Override protected TheBuilder getThis() {
        return this;
    }
    ...
}

Alternatively, drop the generic type parameter, rely on covariant return types and make the code cleaner for clients (although usually they would be using TheBuilder rather than the largely implementation detail of the base class), if making the implementation more verbose.

One alternative is not to use generics, but use overrides:

abstract class AbstractBuilder
{
   public AbstractBuilder foo()
   {
      // set some property
      return this;
   }
}

class TheBuilder extends AbstractBuilder
{
   @Override public TheBuilder foo()
   {
      super.foo(); return this;
   }
   public TheBuilder bar()
   {
      // set some other property
      return this;
   }

   public Object build()
   {
      return new Object();
   }
}

This should help:

abstract class AbstractBuilder<T extends AbstractBuilder<?>>
{
   public AbstractBuilder<T> foo()
   {
      // set some property
      return (AbstractBuilder<T>) this;
   }

   abstract AbstractBuilder<T> bar();
   abstract Object build();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!