【发布时间】:2018-10-02 15:04:34
【问题描述】:
CRTP 模式允许在 Java 中模拟所谓的self types,例如。 g.:
abstract class AbstractFoo<SELF extends AbstractFoo<SELF>> implements Comparable<SELF> {
@Override
public final int compareTo(final SELF o) {
// ...
}
}
final class C1 extends AbstractFoo<C1> {
// ...
}
final class C2 extends AbstractFoo<C2> {
// ...
}
使用上面的代码(Comparable 接口只是为了清晰起见;当然还有其他用例),我可以轻松比较C1 的两个实例:
new C1().compareTo(new C1());
但不是AbstractFoo具体类型不同的后代:
new C1().compareTo(new C2()); // compilation error
但是,这种模式很容易被滥用:
final class C3 extends AbstractFoo<C1> {
// ...
}
// ...
new C3().compareTo(new C1()); // compiles cleanly
此外,类型检查是纯粹的编译时检查,即。 e.可以轻松地将C1 和C2 实例混合在一个TreeSet 中,并将它们相互比较。
Java 中的 CRTP 有什么替代方法可以模拟 self 类型,而不会像上面显示的那样被滥用?
P. S. 我观察到该模式在标准库中没有被广泛使用——只有EnumSet 及其后代实现了它。
【问题讨论】:
-
什么衡量标准决定了替代方案是否比 CRTP更好?这个问题听起来很主观。
-
@jaco0646 好吧,我理解这个问题听起来可能是基于意见的,但我希望任何回复描述可能的替代方案。相应地编辑了问题。
-
如果 any 替代方案是可以接受的,那么问题就变得太宽泛了:没有比较潜在答案的基础。仅供参考,我认为这个问题很有趣,所以我试图让它变得不那么开放。或许,“Java 中有什么替代 CRTP 的方法可以模拟 self 类型而没有滥用的可能性,如上所示?”
-
@jaco0646 谢谢,按照您的建议进行了编辑。
-
@Bass this may be?