我正在尝试为某些构建器类提供一个抽象基类,以便可以轻松地在构建器实现之间重用代码。我希望我的构建器支持方法链接,因此方法必须返回最特定类型的“此”实例。我想我可以使用泛型来做到这一点。不幸的是,我没有使用不安全的操作就无法做到这一点。可能吗?
下面是我如何尝试(及其工作方式)的示例代码。我想避免在“foo()”中强制转换为T(这会导致未经检查的警告),可以这样做吗?
public class Builders
{
public static void main( final String[] args )
{
new TheBuilder().foo().bar().build();
}
}
abstract class AbstractBuilder<T extends AbstractBuilder<?>>
{
public T foo()
{
// set some property
return (T) this;
}
}
class TheBuilder extends AbstractBuilder<TheBuilder>
{
public TheBuilder bar()
{
// set some other property
return this;
}
public Object build()
{
return new Object();
}
}
最佳答案
您想将T
声明为extends AbstractBuilder<T>
中的AbstractBuilder
。
使用abstract protected
方法获取this
类型的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;
}
...
}
或者,如果使实现更加冗长,则删除泛型类型参数,依靠协变量返回类型,并使代码对客户端更整洁(尽管通常,他们将使用
TheBuilder
而不是基类的大部分实现细节)。