有人可以解释下面的,相当复杂的递归通用模板用法吗?
public abstract class Data<E extends Data<E, S>,
S extends Writer<E>> extends Entity<E,S>
在使用递归泛型时,我们应该记住什么,如上所述。这些类型之间的关系和规则将如何,这里 E &amp; 取值
如果有的话,请提供一些有关此类通用用法的资源/链接/书籍。 我知道有一本书谈论这个,有效的Java,Joshua Bloch的第二版(第27项)
答案 0 :(得分:3)
让我们从最简单的
开始S extends Writer<E>
任何类型S的类必须是E类的作者
extends Entity<E,S>
这里只是继承,Data类扩展了Entity类。
E extends Data<E, S>
用于E的任何类本身都必须从Data类继承,并使用自己的类型和与自身兼容的writer继承/实现Data的泛型方法。
E&amp; E之间的关系S应该类似于以下内容:
//E = Example, S = ExampleWriter
public class ExampleWriter implements Writer<Example>{
//...
}
public class Example extends Data<Example,ExampleWriter>{
//...
}
要记住:使用提供Writer<SomeChildOfExample>
或Writer<SomeParentOfExample>
的泛型可能会或可能不会创建编译器错误,这取决于两种泛型类型中定义的泛型方法。
答案 1 :(得分:2)
Data
有两个参数,E
最终必须是自身的实例,而S
必须能够Writer
一个自身的实例(更具体地说,由E
指定的同一类型的实例。最后,Data<E,S>
也符合/继承来自同一Entity
和E
S
参数化的Entity
的功能,并且Data<E,S>
属于Writer<E>
且NumericalData extends Data<NumericalData, NumWriter>
)。
具体实现可能类似于
{p>NumWriter
其中Writer<NumericalData>
实现/扩展NumericalData
和Entity<NumericalData, NumWriter>
也符合Data<E,S>
。
编辑:
为什么会这样?有人可能希望在抽象类中定义泛型方法,这些方法依赖于符合条件Data<E,S>
的参数/返回,但也希望能够返回/使用更明确的类型。例如,在E doSomething(E toThis) { toThis.aDataClassMethod(); return toThis; }
中,可能有
E
该类可以进行第一次调用,因为它知道Data<E,S>
是toThis
,并返回更具体的类型,因为它知道E
是{{1}}。< / p>
说实话,递归泛型通常通常过于聪明的道路。它们可能很有用,但很多时候它们只是“整洁”而且试图围绕一些聪明的东西而不是反之亦然。
答案 2 :(得分:0)
我同意Carl的看法,递归类型往往是“聪明”而牺牲了可用性。然而,有很多情况下Java rtl应该使用这个习惯来强制执行严格的类型安全,并避免我们作为类库使用的猴子桶。
例如,即使 Object 也应该是一个抽象的递归类型,至少要强制执行严格的相等规则:
public abstract class Object<T extends Object<T>> {
...
public boolean equals( o :T ) {
...
}
}
在equals()实现中不再检查instanceof,更重要的是,对equals()调用进行更好的编译时检查。
也就是说,或许更合适,更简单的特征是“自我”型......