Обычное решение - самоограниченные дженерики, как видно из класса Enum
.
interface Example<T extends Example<T>> {
void foo(T t);
}
public class ExampleImpl implements Example<ExampleImpl> {
@Override
public void foo(ExampleImpl example) {
}
}
Как это работает, немного головокружительно, но очень хорошо объяснено здесь например.Здесь также есть очень хороший ответ по этому вопросу здесь .
Обратите внимание, что он не является надежным, поскольку допускает следующее:
public class ExampleImpl2 extends Example<ExampleImpl {
@Override
public void foo(ExampleImpl example) {
}
}
Но на практикесамоограниченная идиома используется для выражения именно того, что вам нужно.
Если вам действительно очень нужен объект параметра, чтобы он всегда был точно таким же классом, как this
, вы должнысделать проверку во время выполнения.(Это также поднимает вопрос о том, зачем вам это нужно, но это отвлечет нас от темы.)