我有一个位置和一个处理位置的处理器。给定位置,客户端可以请求该位置的处理器。我实现了Location
,如下所示:
public abstract class Location<SELF extends Location<SELF>> {
...
public Processor<SELF> processor() {
return new Processor(this);
}
}
我正在创建和使用Location
中的子类,而从未直接使用Location
:
public class SecretLocation extends Location<SecretLocation> {
...
}
我需要处理器上的类型安全,因此只能提供(属于此具体秘密位置类实例的)引用(此处省略),因此使用SELF
和子类,并提供类型化的{{1 }}处理。
现在,我想实现Location
,如下所示:
Processor
但是使用此实现,public class Processor<L extends Location<L>> {
private final L location;
public Processor(L location) {
this.location = location;
}
public L location() {
return location;
}
...
}
中的new Processor(this)
无效。我找到了两种方法来解决此问题,但我不确定哪种方法最好:
在Location
中使用new Processor(this)
而不是new Processor<>(this)
,因此基本上禁用了泛型。
在构造函数中接受Location
而不是Location<L>
,并在L
中接受成员变量。结果是Processor
中的getter location
现在必须返回Processor
而不是上面的Location<L>
。不利之处在于,在L
上创建处理器时,processor.location()
现在永远不会再返回SecretLocation
,而只会返回SecretLocation
。这有点草率,因为现在我再也无法通过处理器取回Location<SecretLocation>
。
作为参考,这是我的第二个解决方案:
SecretLocation
还有什么更好的选择吗?
答案 0 :(得分:3)
在这种情况下,最直接的解决方案可能是这样的:
public abstract class Location<SELF extends Location<SELF>> {
...
public Processor<SELF> processor() {
return new Processor<>( self() );
}
protected abstract SELF self();
}
public class SecretLocation extends Location<SecretLocation> {
...
@Override
protected SecretLocation self() { return this; }
}
问题是给定的界限实际上并未将type参数限制为this
的类型,例如,以下类将编译:
class BadLocation extends Location<SecretLocation> {}
另一种解决方案是使用未经检查的演员表:
return new Processor<>((SELF) this);
这也将起作用,但是如BadLocation
所示,没有真正的限制,this
实际上是SELF
的对象。 (但是,对于abstract
方法解决方案,子类不必从该方法返回this
,因此,在保证正确性方面,都不是完美的解决方案。)