我可以在java中使用方法链接而不执行不安全操作的抽象构建器类吗?
我正在尝试为一些构建器类创建一个抽象基类,这样我就可以轻松地在Builder实现之间重用代码。 我希望我的构建器支持方法链接,因此方法必须返回最具体类型的“this”实例。 我想我可以用generics来做这件事。 不幸的是,如果不使用不安全的操作,我就无法做到这一点。 可能吗?
下面是我如何尝试它(以及它如何工作)的示例代码。 我想避免在“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 { public TheBuilder bar() { // set some other property return this; } public Object build() { return new Object(); } }
您想在AbstractBuilder
中将extends AbstractBuilder
声明为extends AbstractBuilder
。
使用abstract protected
方法来获取T
类型。
abstract class AbstractBuilder> { protected abstract T getThis(); public T foo() { // set some property return getThis(); } } class TheBuilder extends AbstractBuilder { @Override protected TheBuilder getThis() { return this; } ... }
或者,删除generics类型参数,依赖协变返回类型并使代码更清晰(尽管通常它们将使用TheBuilder
而不是基类的大部分实现细节),如果使实现更加冗长。
一种替代方法是不使用generics,而是使用覆盖:
abstract class AbstractBuilder { public AbstractBuilder foo() { // set some property return this; } } class TheBuilder extends AbstractBuilder { @Override public TheBuilder foo() { super.foo(); return this; } public TheBuilder bar() { // set some other property return this; } public Object build() { return new Object(); } }
这应该有所帮助:
abstract class AbstractBuilder> { public AbstractBuilder foo() { // set some property return (AbstractBuilder ) this; } abstract AbstractBuilder bar(); abstract Object build(); }