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