在generics中接受自身作为类型参数会有什么用处

我在一个不相关的问题上看到了一些代码,但它让我感到好奇,因为我从未在Java Generics中看到过这样的构造。 创建一个可以作为类型参数本身或其自身后代的generics类会有什么用处。 这是一个例子:

abstract class A<E extends A> { abstract void foo(E x); } 

我想到的第一件事就是将列表作为参数的列表。 使用这段代码感觉很奇怪,你如何声明A类型的变量? 递归声明!?

这甚至有用吗? 如果是这样的话你们在代码中看到了吗? 它是如何使用的?


编辑

事实上,事实certificate我的问题与这个只有不同的措辞相同,但这个问题的答案也会回答我的问题。

同样感谢参考奇怪的重复模板模式 ,该模式给出了一些历史背景和对该主题的进一步解释。

这篇旧博客文章可能会给我们Java家伙提供最好的解释。

现在很难在这里选择一个正确的答案,因为它们都很有帮助,所以我会选择最终产生最多阅读材料的那个(参考上文)

generics不仅仅适用于列表之类的容器。 这种“扩展自身”类型参数用于让超类在方法参数和返回类型等位置引用子类,即使在编译超类时没有可用的实际特定子类。 它类似于C ++中奇怪的重复模板模式 。

您的示例的子类将声明为

 class Foo extends A 

并inheritance了foo()方法

 void foo(Foo x) 

看看A如何定义一个采用Foo参数的方法,即使它实际上并不知道Foo

是的,这种事情很不寻常,但并非闻所未闻:内置的Enum类使用了类似的技巧。

如果没有这个,方法foo的参数就不能绑定到E类型。

如果你有这个抽象类的实现B ,你现在可以强制执行该方法, foo也要求它的参数是B

  class B extends A { void foo (B x){} } 

没有它, foo将不得不采取任何类型的A

我同意这个语法不够优雅。