给定一个类层次结构,其中基类定义了递归自类型:
abstract class A<T extends A<T>> { }
如何声明另一个类(在 T 中不应该是通用的,因为这样的 T 可能在对象的生命周期内变化),其字段可以保存 A 的任何子类?
以下不起作用:
public class B {
//fails to compile, because the capture of ? is not sufficiently narrow
private A<?> a;
public <T extends A<T>> setA(T a) {
this.a = a;
}
}
-- 问题结束 --
我注意到一些 StackOverflow 成员倾向于用“你为什么要这样做?”来解决某些难题。以下是我使用此模式的理由 - 您可以注意到 Java 标准库还在 Enum 类的定义中使用递归自类型:Enum<E extends Enum<E>>
。这个问题可以类似地问为“如何定义类型的字段Enum<?>
.
理由示例:
abstract class A<T extends A<T>> {
public abtract T self();
public B<T> bify(Bifyer bifyer) {
return bifyer.bify(self());
}
}
与子类:
class ASub1 extends A<ASub1> {
public ASub1 self() { return this; }
}
class ASub2 extends A<ASub2> {
public ASub2 self() { return this; }
}
绑定到并行类层次结构:
abstract class B<T extends A<T>> {
}
class BSub1<T extends A<T>> implements B<T> { }
class BSub2<T extends A<T>> implements B<T> { }
//and others
并且通过 Bifyer 接口的实现管理 B 实例的生成:
interface Bifyer {
B<ASub1> bify(ASub1 asub1);
B<ASub2> bify(ASub2 asub2);
}
此接口的实现可能会为 B 返回 BSub1 或 BSub2。这本质上是访问者模式的应用,其中 Bifyer 是访问者,但与标准访问者不同的是,accept 方法返回一个值而不是 void。这提供了一个模块化框架,可以在其中指定不同的 Bifyer 实现来为 Bify 方法提供替代行为和返回类型 - 例如 B 的每个子类都有一个。