在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
我同意这个语法不够优雅。