Java递归通用模板:这是什么意思... S扩展了Writer <e>&gt;扩展实体<e,s> </e,s> </e>

时间:2011-01-11 11:10:01

标签: java generics recursion templating

有人可以解释下面的,相当复杂的递归通用模板用法吗?

public abstract class Data<E extends Data<E, S>,
                           S extends Writer<E>> extends Entity<E,S>

在使用递归泛型时,我们应该记住什么,如上所述。这些类型之间的关系和规则将如何,这里 E &amp; 取值

如果有的话,请提供一些有关此类通用用法的资源/链接/书籍。 我知道有一本书谈论这个,有效的Java,Joshua Bloch的第二版(第27项)

3 个答案:

答案 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>也符合/继承来自同一EntityE S参数化的Entity的功能,并且Data<E,S>属于Writer<E>NumericalData extends Data<NumericalData, NumWriter>)。

具体实现可能类似于

{p> NumWriter其中Writer<NumericalData>实现/扩展NumericalDataEntity<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()调用进行更好的编译时检查。

也就是说,或许更合适,更简单的特征是“自我”型......