Проблема в том, что нет способа ссылаться на тип «этого самого класса». Вот почему вы должны использовать конструкции, такие как abstract class Base<T extends Base<T>>
. Но, как многие из упомянутых в комментариях, ничто не запрещает вам определять Subclass1 extends <Subclass2>
. Существует только синтаксический способ гарантировать, что T
является «этим самым классом».
Вы можете, однако, обеспечить соблюдение этой гарантии во время выполнения. Вы можете использовать что-то вроде TypeTools или другие методы для извлечения используемого общего типа и убедиться, что текущий экземпляр имеет этот тип. Это, вероятно, приведет к чему-то вроде:
public abstract class Base<T extends Base<T>> {
protected Base() {
final Class<?> t = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
if (!t.isInstance(this)) {
throw new IllegalArgumentException();
}
}
public T getInstance() {
@SuppressWarnings("unchecked")
T thisIsT = (T) this;
return thisIsT;
}
}
Этот класс может быть реализованным:
public class Extension1 extends Base<Extension1> {}
Но это не:
public class Extension2 extends Base<Extension1> {}
Base
конструктор гарантирует, что this
является экземпляром T
поэтому литой this
до T
является безопасным.
Это сломается, если я решит сделать это: 'class ChildClass2 расширяет ParentClass'. Теперь я не совсем понимаю, чего вы хотите достичь или почему вы хотите достичь этого. Если вы хотите соответствующим образом обновить свой вопрос, я могу дать ответ. –
@JoeC У меня есть работы, но мне требуется, чтобы я включил «this» в родительский класс в T. Он уже должен знать, что «это» является экземпляром T, поэтому мне было интересно, было ли более элегантное решение что просто не было достаточно умным, чтобы думать. Либо тот, который не требовал от меня броска, либо тот, который возвращал дочерний экземпляр без использования дженериков вообще. –
Попробуйте то, что у вас есть с подклассом, который я предложил, и дайте мне знать, если он все еще работает. –