Eric
Eric

Reputation: 340

Java avoid class cast warning in hierarchical Builder pattern

Is there a way to avoid the unchecked class cast in this hierarchical Builder pattern?

public abstract class BaseBuilder <T, B extends BaseBuilder<T,B>> {

  public B setB1(String b1) {
    this.b1 = b1;
    return (B) this; // can I make this unchecked cast go away?
  }

  abstract public T build();

  String b1;
}

and no, the answer is not:

return B.class.cast(this);

and yes, I know I could use @SuppressWarnings

Upvotes: 4

Views: 1888

Answers (3)

newacct
newacct

Reputation: 122489

As said before, this can't be done, because it is not safe. B extends BaseBuilder<T,B>, but BaseBuilder<T,B> (type of this) does not extend B. Recursive bounds are almost NEVER useful in Java, and do not give you the self-type. You should get rid of it.

You can add an abstract method such that implementing classes must give an instance of B:

public abstract class BaseBuilder <T, B> {

  abstract public B getB();

  public B setB1(String b1) {
    this.b1 = b1;
    return getB();
  }

  abstract public T build();

  String b1;
}

Upvotes: 5

Julien May
Julien May

Reputation: 2051

besides of what louis said the following is a somewhat nice design:

public abstract class BaseBuilder ... {
    ...
    public B setB1(String b1) {
        this.b1 = b1;
        return self();
    }

    abstract protected B self();
    ...
}

public class SomeBuilder extends BaseBuilder ... {
    @override
    protected SomeBuilder self() {
        return this;
    }
}

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198211

Yes; return BaseBuilder<T, B> and force subclasses to override setB1 to return themselves.

Upvotes: 2

Related Questions