Java 自限定类型 (Self-bounded Types)
Feb 27, 2021
解释了一下自限定类型 (self-bounded types)
让人懵逼的模式。(我开始写这篇文章的时候,还不是很看懂,写完应该懂了 🤣
1 | class SelfBounded<T extends SelfBounded<T>> { //... |
试图理解一下
先从简单的泛型开始
1 | class A<T> { |
类 A
中有一个类型参数 T
,实例变量 property
的类型,setProperty
方法接受一个该类型的参数,getProperty
方法返回值也是该类型。
现在希望从类 A
中的参数和返回的类型都是类型 B
。所以先定义一下类 B
然后让新的类 C
继承与 A<B>
,结果如下:
1 | class B {} |
可以把上述定义简化一下,在定义 B
时直接继承于 A<B>
,让 B
出现在自己在继承的类中,这个叫奇异递归泛型(Curiously recurring generics, CRG)
The “curiously recurring” part refers to the fact that your class appears, rather curiously, in its own base class. (“奇特递归” 指你的类奇特的出现在自己的父类中)
1 | class B extends A<B> {} |
在这模式中可以把 A
看作一个模板,B
套用了模板 A
。
如果把 A
看作一个模板的话,它会有一个问题,使用模板(继承于A
)的类没限制只能使用自己为类型参数,就是说类 B
继承 A
的时候 A
的类型参数可以不是 B
。
1 | class C {} |
为了解决这个问题,即限制继承的类只能使用它自己为类型参数可以把 A
里的泛型范围加一个上限。如下:
1 | class A<T extends A<T>> {} |
现在继承于 A 的类只能提供自己为泛型参数。
1 | class C {} |
这不就是让人懵逼的模式么 🤣
1 | class A<T extends A<T>> {} |
参考资料
- Bruce Eckel, Thinking in Java 4th edition, Self-bounded Types
- Curiously recurring template pattern, https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern