mat*_*t b 1 java generics type-bounds
假设我有几个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);
}
Run Code Online (Sandbox Code Playgroud)
如果我实现getDao()它的参数是一个Class对象,例如
private <T extends BaseObject> GenericDao<T> getDao(Class<T> clazz) { ... }
Run Code Online (Sandbox Code Playgroud)
然后调用getDao(object.getClass()的create()方法无法编译-编译器似乎解释的返回类型getDao()为
GenericDao<? extends BaseContractObject>
Run Code Online (Sandbox Code Playgroud)
而不是认识到这getDao(Class<T>)将使我返回GenericDao相同的类型T.
有人可以解释为什么会这样吗?据我所知,相同类型绑定或通配符的重复出现不一定是指同一类型; 然而,似乎编译器应该从签名中识别出getDao(Class<T>)传入的T应该与返回的T相同(但显然它不能识别这个,为什么我无法理解的部分).
如果我改为定义getDao签名
private <T extends BaseContractObject> GenericDao<T> getDao(T obj) { ... }
Run Code Online (Sandbox Code Playgroud)
然后在编译create()看起来像的实现时没有问题
public <T extends BaseContractObject> long create(T object) {
return getDao(object).save(object);
}
Run Code Online (Sandbox Code Playgroud)
那么为什么编译器能够在这种情况下识别T传递给的参数在返回类型中getDao(T)是相同T的,而在参数是Class<T>什么时它无法识别?
object.getClass()对象是类型的表达式T extends BaseObject返回a Class<? extends BaseObject>,而不是Class<T>正如人们所期望的那样.因此,getDao()返回它收到的相同类型的DAO; 它只是没有收到预期的类型.