Вы можете сделать это с использованием небезопасных слепки, которые вы знаете, будет в безопасности:
static class NoConstraint<T> implements Constraint<T> {
private static final Constraint rawInstance = new NoConstraint();
public static <T> Constraint<T> instance() {
@SupressWarnings("unchecked")
Constraint<T> generic = rawInstance;
return generic;
}
@Override
public T constrain(T unconstrainedValue) {
return unconstrainedValue;
}
}
Излишне говорить, что вы должны сделать это, только если вы доказали себе, что это всегда безопасно (который в этом случае, вероятно, довольно легко сделать).
Это не необычный трюк в подобных ситуациях. Например, Collections.emptyList
(и аналогичные методы в этом классе) используют эту технику.
Заметим также, что T
в методе instance()
является отличается от T
в Constraint<T>
, несмотря на то, что они разделяют то же имя. T
Constraint доступен только в контексте экземпляра, а не в статическом контексте, поэтому мы должны объявить общий параметр для статического метода. В большинстве случаев затенение имен, подобных этому, опасно; в таких случаях я считаю это полезным, как наглядное напоминание о том, что и T
s тесно связаны с типичным пользователем.
Почему у вашей модели класса NoConstraint есть статический модификатор? Предполагается, что это внутренний класс? – alainlompo