Шаблон CRTP позволяет эмулировать так называемые типы собственной личности в Java , например:
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
Кроме того, проверки типовчисто во время компиляции, то есть можно легко смешивать C1
и C2
экземпляров в одном TreeSet
и сравнивать их друг с другом.
Какая альтернатива CRTP в Java эмулирует собственные типы без возможности злоупотребления, как показано выше?
PS Я наблюдаю, как шаблон широко не используется в стандартной библиотеке- только EnumSet
и его потомки реализуют его.