尝试实例化自引用泛型实例时 class,如何处理自引用类型参数

When attempting to instantiate an instance of a self-referential generic class, how you handle the self-reference type parameter

我是设计流畅、可扩展界面的新手。我有一个实现接口的构建器链 classes,接口和构建器实现都采用自引用类型参数。

注意:这与我的 previous question 相关,在尝试 这种 接口采用自引用类型参数也是:

界面如下:

public interface ILoadableBuilder<C extends ILoadable,T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>> {
    T getState();
    B setComponentClass(final Class<C> componentClass);
    B setDriver(final WebDriver driver);
    B setLoadTimeoutInSeconds(final @Nonnegative int loadTimeoutInSeconds);
    B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator);
}

这是一个实现,它也采用自引用类型参数。 class 实现采用参数的原因是我希望它是可扩展的,这样其他构建器就可以扩展这个 class 并继承它的所有行为,并且可以按任何顺序调用 setter 和return 类型将是正确的:

public class LoadableBuilder<C extends ILoadable,T extends ILoadableBean,B extends ILoadableBuilder<C,T,B>> implements
        ILoadableBuilder<C,T,B> {

    private final T componentBean;
    private IEnumeratorBean<? extends IEnumerable<?>,?> enumerator;
    private Class<C> componentClass;

    public LoadableBuilder(final T componentBean) {
        this.componentBean = componentBean;
    }

    public final T getState() {
        return componentBean;
    }

    public final B setComponentClass(final Class<C> componentClass) {
        this.componentClass = componentClass;
        return (B)this;
    }

    public final B setDriver(final WebDriver driver) {
        getState().setDriver(driver);
        return (B)this;
    }

    public final B setLoadTimeoutInSeconds(final int loadTimeoutInSeconds) {
        getState().getLoadTimeoutInSeconds();
        return (B)this;
    }

    public B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator) {
        this.enumerator = enumerator;
        return (B)this;
    }
}

我的问题是,您如何在不必将类型参数传递给客户端的情况下实例化此实现的实例 class?说,我想在 class 中声明一个成员变量,它像这样使用构建器:

public ClientClass<C,T> {

    private ILoadableBuilder<C,T,_what do I put here????_> builder = new LoadableBuilder<C,T,_what do I put here?????_>();

}

对于一个方法,没什么大不了的,因为我可以做到:

public <B extends ILoadableBuilder<C,T,B>> void useABuilder() {
    ILoadableBuilder<C,T,B> builder = new LoadableBuilder<C,T,B>();
}

编辑:

ClientClass 想要构建一个实现 ILoadable 接口的对象。我有很多扩展 ILoadableBuilder 的构建器来构建实现接口的对象,这些接口是 ILoadable 的子类型。我的想法是,我希望能够为 ILoadable 下的继承层次结构中的任何对象获取构建器,它们本身在必要时是可扩展的。

您有两个选择:

  • 使LoadableBuilder不可扩展,声明为

    即可
    public class LoadableBuilder<C extends ILoadable, T extends ILoadableBean>
        implements ILoadableBuilder<C,T,LoadableBuilder<C,T>>
    
  • 如果你想让它可以扩展,那就让它总是有必要扩展它。设 LoadableBuilder 为 "abstract"。定义一个简单的实现,它只是将它子类化,没有额外的东西用于 "basic" 行为:

    public abstract class LoadableBuilder<C extends ILoadable,
        T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>>
        implements ILoadableBuilder<C,T,B> {
        //...
    }
    
    public class BasicLoadableBuilder<C extends ILoadable, T extends ILoadableBean>
        extends LoadableBuilder<C,T, BasicLoadableBuilder<C,T>> {
    }