мой вопрос довольно теоретичен... Это подпись класса Class.asSubclass(Javadoc):
public <U> Class<? extends U> asSubclass(Class<U> clazz)
Почему в возвращаемом типе используются шаблоны подстановочных знаков? Из моего понимания дженериков лучшая подпись может быть:
public <U> Class<U> asSubclass(Class<U> clazz)
потому что вы можете наверняка сделать
Class<? extends U>
к более простой
Class<U>
Блох в своей книге "Эффективная Java" рекомендует (стр. 137, пункт 28):
Не используйте типы подстановочных знаков в качестве возвращаемых типов. Вместо того, чтобы предоставлять дополнительную гибкость для ваших пользователей, это заставит их использовать подстановочные типы в клиентском коде.
В чем причина этого выбора? Что мне не хватает? Большое вам спасибо заранее.
Edit: Как предлагает @egelev, я мог бы действительно сформулировать свой вопрос по-другому... на самом деле возврат входного параметра "как есть" будет бессмысленным. Итак, настоящая проблема: Какова реальная полезность метода Class.asSubclass по сравнению с обычным литом? Оба будут бросать ClassCastException в случае проблем с литой.
MAYBE он был добавлен во избежание неконтролируемого кастинга в конкретной ситуации: когда вы передаете результат метода asSubclass непосредственно другому методу, запрашивая параметр с ограниченным типом, как здесь (взято из Effective Java, стр. 146):
AnnotatedElement element;
...
element.getAnnotation(annotationType.asSubclass(Annotation.class));
Подпись вышеописанного метода:
<T extends Annotation> T getAnnotation(Class<T> annotationClass);
Мне кажется, что метод asSubclass - это всего лишь способ сделать (на самом деле!) непроверенный листинг без надлежащего предупреждения о компиляторе...
И это, в конце концов, повторно предложит мой прежний вопрос: подпись
public <U> Class<U> asSubclass(Class<U> clazz)
будет одинаково эффективным (даже если это странно, я признаю это)! Он будет полностью совместим с примером getAnnotation и не будет ограничивать клиентский код, заставляя его использовать бессмысленные подстановочные файлы.
Edit2: Я думаю, мой общий вопрос был решен; Большое спасибо. Если у кого-то есть другие хорошие примеры о правильности подписи asSubclass, добавьте их в дискуссию, я хотел бы увидеть полный пример использования asSubclass с моей подписью и, по-видимому, не работать.