解释了一下自限定类型 (self-bounded types)

让人懵逼的模式。(我开始写这篇文章的时候,还不是很看懂,写完应该懂了 🤣

1
class SelfBounded<T extends SelfBounded<T>> { //...

试图理解一下

先从简单的泛型开始

1
2
3
4
5
class A<T> {
T property;
void setProperty(T t) { property = t; }
T getProperty() { return property; }
}

A 中有一个类型参数 T,实例变量 property 的类型,setProperty 方法接受一个该类型的参数,getProperty 方法返回值也是该类型。

现在希望从类 A 中的参数和返回的类型都是类型 B。所以先定义一下类 B 然后让新的类 C 继承与 A<B>,结果如下:

1
2
3
class B {}

class C extends A<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
2
3
class C {}

class B extends A<C> {}

为了解决这个问题,即限制继承的类只能使用它自己为类型参数可以把 A 里的泛型范围加一个上限。如下:

1
class A<T extends A<T>> {} 

现在继承于 A 的类只能提供自己为泛型参数。

1
2
3
4
5
class C {}

class B extends A<C> {} // 不合法,会编译失败

class B extends A<B> {} // 合法

这不就是让人懵逼的模式么 🤣

1
class A<T extends A<T>> {} 

参考资料

  1. Bruce Eckel, Thinking in Java 4th edition, Self-bounded Types
  2. Curiously recurring template pattern, https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern