Java避免在层次Builder模式中出现类转换警告

4

在这个分层的Builder模式中,有没有方式避免未经检查的类转换?

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;
}

而且,答案不是:“

”。
return B.class.cast(this);

是的,我知道我可以使用@ SuppressWarnings。


4
很遗憾,Java不允许强制B成为“当前”类,并且未检查的警告存在于此以提醒您。class MBB1<String, MBB2>class MBB2<String, MBB2>,你期望MBB1.setB1()会做什么? - ignis
1
相关:https://dev59.com/vGs05IYBdhLWcg3wQvke - Paul Bellora
3个回答

5
如前所述,这是不安全的,因此无法完成。 B 扩展 BaseBuilder<T,B>,但 BaseBuilder<T,B>(即 this 的类型)并没有扩展 B。在 Java 中,递归边界几乎从不有用,并且不会给你自我类型。您应该将其去掉。
您可以添加一个抽象方法,使实现类必须提供 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;
}

我没有想到过这种恶作剧,比如:public class EvilBuilder extends BaseBuilder<Thing1, Thing1Builder> {... - Eric

2
是的,返回BaseBuilder<T, B>并强制子类重写setB1方法以返回它们自己。

1
@Saintali:它们不必返回自己。它们只需要返回一个 B 的实例。所以你只需要有一个返回类型为 B 的函数即可。 - newacct

1

除了路易斯所说的之外,以下是一个相当不错的设计:

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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接