Допустим, у меня есть несколько POJO, которые расширяют общий супертип, BaseObject
.
У меня есть GenericDao
, который объявлен как public interface GenericDao<T>
.
Для каждого конкретного типа DAO у меня есть интерфейс, который расширяет общий тип и ограничивает его конкретным типом (public interface UserDao extends GenericDao<User>
), а затем реализует специфичный для типа DAO.
В классе, который пытается использовать несколько реализаций GenericDao
, у меня есть метод, который выглядит как
public <T extends BaseObject> long create(T object) {
return getDao(object.getClass()).save(object);
}
Если я реализую getDao()
, так что его параметр является объектом Class
, такойas
private <T extends BaseObject> GenericDao<T> getDao(Class<T> clazz) { ... }
Тогда вызов getDao(object.getClass()
в методе create()
не компилируется - кажется, что компилятор интерпретирует тип возврата getDao()
как
GenericDao<? extends BaseContractObject>
чем признание того, что getDao(Class<T>)
вернет мне GenericDao
того же типа T
.
Может кто-нибудь объяснить, почему это так?Я понимаю, что повторяющиеся появления одного и того же типа с привязкой или подстановочным знаком необязательно относятся к одному и тому же типу;однако кажется, что компилятор должен признать из сигнатуры getDao(Class<T>)
, что переданный T должен быть тем же самым возвращенным T (но, очевидно, он не способен это распознать, , почему является частью Iне понять).
Если я вместо этого определю сигнатуру getDao
как
private <T extends BaseContractObject> GenericDao<T> getDao(T obj) { ... }
Тогда нет проблем при компиляции реализации create()
, которая выглядит как
public <T extends BaseContractObject> long create(T object) {
return getDao(object).save(object);
}
Так почему же в этом случае компилятор может распознать, что аргумент T
, переданный getDao(T)
, совпадает с T
в возвращаемом типе, тогда как он не смог распознать это, когда аргумент былClass<T>