Dima Dima - 3 months ago 14
Java Question

Java generic builder

Suppose I need some

DerivedBuilder
to extend some
BaseBuilder
. Base builder has some method like
foo
(which returns
BaseBuilder
). Derived builder has method
bar
. Method
bar
should be invoked after method
foo
. In order to do it I can override
foo
method in
DerivedBuilder
like this:

@Override
public DerivedBuilder foo() {
super.foo();
return this;
}


The problem is that
BaseBuilder
has a lot of methods like
foo
and I have to override each one of them. I don't want to do that so I tried to use generics:

public class BaseBuilder<T extends BaseBuilder> {
...

public T foo() {
...
return (T)this;
}
}

public class DerivedBuilder<T extends DerivedBuilder> extends BaseBuilder<T> {
public T bar() {
...
return (T)this;
}
}


But the problem is that I still can not write

new DerivedBuilder<DerivedBuilder>()
.foo()
.bar()


Even though
T
here is
DerivedBuilder
. What can I do in order to not to override a lot of functions?

Answer

Your problem is the definition of DerivedBuilder:

class DerivedBuilder<T extends DerivedBuilder>;

And then instantiating it with a type erased argument new DerivedBuilder<DerivedBuilder<...what?...>>().

You'll need a fully defined derived type, like this:

public class BaseBuilder<T extends BaseBuilder> {
    public T foo() {
        return (T)this;
    }
}

public class DerivedBuilder extends BaseBuilder<DerivedBuilder> {
    public DerivedBuilder bar() {
        return this;
    }
}

Check ideone.com.

Comments