![](/img/trans.png)
[英]What does this Java syntax mean? (` Class<? extends E> clazz`)
[英]Java Recursive generic template: what does this mean by … S extends Writer<E>> extends Entity<E,S>
有人可以解释以下相当复杂的递归通用模板用法吗?
public abstract class Data<E extends Data<E, S>,
S extends Writer<E>> extends Entity<E,S>
如上所述,在使用递归泛型时我们应该记住什么。 这些类型(这里是E & S)之间的关系和规则如何?
如果有的话,请提供一些有关这种通用用法的资源/链接/书籍。 我知道一本关于这方面的书,《有效的Java》,约书亚·布洛赫(Joshua Bloch)第二版(第27项)
让我们从最简单的开始
S extends Writer<E>
任何类型为S的类都必须是类E的编写者
extends Entity<E,S>
只是继承,Data类扩展了Entity类。
E extends Data<E, S>
用于E的任何类都必须本身从Data类继承,并使用其自身的类型和与其自身兼容的writer继承/实现Data的通用方法。
E&S之间的关系应如下所示:
//E = Example, S = ExampleWriter
public class ExampleWriter implements Writer<Example>{
//...
}
public class Example extends Data<Example,ExampleWriter>{
//...
}
请记住:使用泛型提供Writer<SomeChildOfExample>
或Writer<SomeParentOfExample>
可能会或可能不会产生编译器错误,这取决于这两种泛型类型中定义的泛型方法。
Data
具有两个参数, E
必须最终成为其自身的实例,而S
必须具有Writer
自身的实例的能力(更具体地说,是E
指定的自身的同类实例)。 最后, Data<E,S>
还具有相同的E
和S
参数化的Entity
(即, Entity
属于Data<E,S>
和Writer<E>
)的资格/继承能力。
具体的实现可能看起来像
NumericalData extends Data<NumericalData, NumWriter>
其中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
坦白地说,递归泛型通常是通往太聪明的道路。 它们可能很有用,但是很多时候它们只是“精巧”的,人们试图将问题转向聪明的事物,而不是相反。
我同意Carl的观点,递归类型倾向于“聪明”,但会牺牲可用性。 但是,在很多情况下,Java rtl应该采用这种惯用法来强制严格的类型安全性并避免我们作为类库拥有的一堆猴子。
例如,即使Object至少也应该是抽象递归类型,以强制执行严格的相等性规则:
public abstract class Object<T extends Object<T>> {
...
public boolean equals( o :T ) {
...
}
}
equals()实现中没有更多的instanceof检查,更重要的是,equals()调用的编译时检查更好。
也就是说,也许更合适,更简单的功能应该是“ Self”类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.