Как уже упоминалось в комментариях, это невозможно реализовать во время компиляции.Есть хитрость, чтобы заставить его терпеть неудачу во время выполнения.
Что вы делаете, это запрашиваете реализующие классы передать свой собственный класс параметра типа абстрактному конструктору с аргументом, типизированным классом параметра типа.
Конструктор родительского класса проверяет, чтодействительно, этот класс является тем же классом, что и класс, который соответствует параметру типа.
abstract class BsNode<T extends BsNode<T>> {
protected BsNode(final Class<T> clazz) {
if (!this.getClass().equals(clazz))
throw new IllegalArgumentException("invalid mixture of node types");
}
}
class AvlNode extends BsNode<AvlNode> {
public AvlNode() {
super(AvlNode.class); // works!!!
}
}
class RBNode extends BsNode<AvlNode> {
public RBNode() {
// two possible super calls:
super(AvlNode.class); // fails at run-time.
// or
super(RBNode.class); // fail at compilation-time.
}
}
Если у вас есть формальный процесс сборки как часть вашего программного обеспечения, которое содержит тестирование, возможно, имеет смысл оставитьограниченная проверка производственного кода (экономия времени вычислений) и включение его в ваши юнит-тесты.